Showing 5 of 33 files from the diff.

@@ -0,0 +1,82 @@
Loading
1 +
pragma solidity ^0.5.16;
2 +
3 +
// Inheritance
4 +
import "./Owned.sol";
5 +
import "./MixinResolver.sol";
6 +
import "./interfaces/ISynthetixBridgeToBase.sol";
7 +
8 +
// Internal references
9 +
import "./interfaces/ISynthetix.sol";
10 +
11 +
// solhint-disable indent
12 +
import "@eth-optimism/rollup-contracts/build/contracts/bridge/interfaces/CrossDomainMessenger.interface.sol";
13 +
14 +
15 +
contract SynthetixBridgeToBase is Owned, MixinResolver, ISynthetixBridgeToBase {
16 +
    uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: verify value
17 +
18 +
    /* ========== ADDRESS RESOLVER CONFIGURATION ========== */
19 +
    bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
20 +
    bytes32 private constant CONTRACT_SYNTHETIX = "Synthetix";
21 +
    bytes32 private constant CONTRACT_SYNTHETIX_BRIDGE_TO_OPTIMISM = "base:SynthetixBridgeToOptimism";
22 +
23 +
    bytes32[24] private addressesToCache = [
24 +
        CONTRACT_EXT_MESSENGER,
25 +
        CONTRACT_SYNTHETIX,
26 +
        CONTRACT_SYNTHETIX_BRIDGE_TO_OPTIMISM
27 +
    ];
28 +
29 +
    //
30 +
    // ========== CONSTRUCTOR ==========
31 +
32 +
    constructor(address _owner, address _resolver) public Owned(_owner) MixinResolver(_resolver, addressesToCache) {}
33 +
34 +
    //
35 +
    // ========== INTERNALS ============
36 +
37 +
    function messenger() internal view returns (ICrossDomainMessenger) {
38 +
        return ICrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER, "Missing Messenger address"));
39 +
    }
40 +
41 +
    function synthetix() internal view returns (ISynthetix) {
42 +
        return ISynthetix(requireAndGetAddress(CONTRACT_SYNTHETIX, "Missing Synthetix address"));
43 +
    }
44 +
45 +
    function synthetixBridgeToOptimism() internal view returns (address) {
46 +
        return requireAndGetAddress(CONTRACT_SYNTHETIX_BRIDGE_TO_OPTIMISM, "Missing Bridge address");
47 +
    }
48 +
49 +
    // ========== PUBLIC FUNCTIONS =========
50 +
51 +
    // invoked by user on L2
52 +
    function initiateWithdrawal(uint amount) external {
53 +
        // instruct L2 Synthetix to burn this supply
54 +
        synthetix().burnSecondary(msg.sender, amount);
55 +
56 +
        // create message payload for L1
57 +
        bytes memory messageData = abi.encodeWithSignature("completeWithdrawal(address,uint256)", msg.sender, amount);
58 +
59 +
        // relay the message to Bridge on L1 via L2 Messenger
60 +
        messenger().sendMessage(synthetixBridgeToOptimism(), messageData, CROSS_DOMAIN_MESSAGE_GAS_LIMIT);
61 +
62 +
        emit WithdrawalInitiated(msg.sender, amount);
63 +
    }
64 +
65 +
    // ========= RESTRICTED FUNCTIONS ==============
66 +
67 +
    // invoked by Messenger on L2
68 +
    function mintSecondaryFromDeposit(address account, uint amount) external {
69 +
        // ensure function only callable from the L2 bridge via messenger (aka relayer)
70 +
        require(msg.sender == address(messenger()), "Only the relayer can call this");
71 +
        require(messenger().xDomainMessageSender() == synthetixBridgeToOptimism(), "Only the L1 bridge can invoke");
72 +
73 +
        // now tell Synthetix to mint these tokens, deposited in L1, into the same account for L2
74 +
        synthetix().mintSecondary(account, amount);
75 +
76 +
        emit MintedSecondary(account, amount);
77 +
    }
78 +
79 +
    // ========== EVENTS ==========
80 +
    event MintedSecondary(address indexed account, uint amount);
81 +
    event WithdrawalInitiated(address indexed account, uint amount);
82 +
}
0 83
imilarity index 50%
1 84
ename from contracts/SecondaryDeposit.sol
2 85
ename to contracts/SynthetixBridgeToOptimism.sol

@@ -128,10 +128,6 @@
Loading
128 128
        return getTradingRewardsEnabled();
129 129
    }
130 130
131 -
    function maximumDeposit() external view returns (uint) {
132 -
        return getMaximumDeposit();
133 -
    }
134 -
135 131
    // ========== RESTRICTED ==========
136 132
137 133
    function setTradingRewardsEnabled(bool _tradingRewardsEnabled) external onlyOwner {
@@ -252,11 +248,6 @@
Loading
252 248
        emit AggregatorWarningFlagsUpdated(_flags);
253 249
    }
254 250
255 -
    function setMaximumDeposit(uint _maxDeposit) external onlyOwner {
256 -
        flexibleStorage().setUIntValue(SETTING_CONTRACT_NAME, SETTING_MAXIMUM_DEPOSIT, _maxDeposit);
257 -
        emit MaximumDepositUpdated(_maxDeposit);
258 -
    }
259 -
260 251
    // ========== EVENTS ==========
261 252
    event TradingRewardsEnabled(bool enabled);
262 253
    event WaitingPeriodSecsUpdated(uint waitingPeriodSecs);
@@ -272,5 +263,4 @@
Loading
272 263
    event MinimumStakeTimeUpdated(uint minimumStakeTime);
273 264
    event DebtSnapshotStaleTimeUpdated(uint debtSnapshotStaleTime);
274 265
    event AggregatorWarningFlagsUpdated(address flags);
275 -
    event MaximumDepositUpdated(uint maxDeposit);
276 266
}

@@ -5,7 +5,7 @@
Loading
5 5
6 6
7 7
contract MintableSynthetix is Synthetix {
8 -
    bytes32 private constant CONTRACT_SECONDARYDEPOSIT = "SecondaryDeposit";
8 +
    bytes32 private constant CONTRACT_SYNTHETIX_BRIDGE = "SynthetixBridgeToBase";
9 9
10 10
    constructor(
11 11
        address payable _proxy,
@@ -14,19 +14,19 @@
Loading
14 14
        uint _totalSupply,
15 15
        address _resolver
16 16
    ) public Synthetix(_proxy, _tokenState, _owner, _totalSupply, _resolver) {
17 -
        appendToAddressCache(CONTRACT_SECONDARYDEPOSIT);
17 +
        appendToAddressCache(CONTRACT_SYNTHETIX_BRIDGE);
18 18
    }
19 19
20 20
    /* ========== VIEWS ======================= */
21 21
22 -
    function secondaryDeposit() internal view returns (address) {
23 -
        return requireAndGetAddress(CONTRACT_SECONDARYDEPOSIT, "Resolver is missing SecondaryDeposit address");
22 +
    function synthetixBridge() internal view returns (address) {
23 +
        return requireAndGetAddress(CONTRACT_SYNTHETIX_BRIDGE, "Resolver is missing SynthetixBridgeToBase address");
24 24
    }
25 25
26 26
    /* ========== RESTRICTED FUNCTIONS ========== */
27 27
28 28
    function mintSecondary(address account, uint amount) external {
29 -
        require(msg.sender == secondaryDeposit(), "Can only be invoked by the SecondaryDeposit contract");
29 +
        require(msg.sender == synthetixBridge(), "Can only be invoked by the SynthetixBridgeToBase contract");
30 30
31 31
        tokenState.setBalanceOf(account, tokenState.balanceOf(account).add(amount));
32 32
        emitTransfer(address(this), account, amount);
@@ -34,7 +34,7 @@
Loading
34 34
    }
35 35
36 36
    function burnSecondary(address account, uint amount) external {
37 -
        require(msg.sender == secondaryDeposit(), "Can only be invoked by the SecondaryDeposit contract");
37 +
        require(msg.sender == synthetixBridge(), "Can only be invoked by the SynthetixBridgeToBase contract");
38 38
39 39
        tokenState.setBalanceOf(account, tokenState.balanceOf(account).sub(amount));
40 40
        emitTransfer(account, address(0), amount);

@@ -3,46 +3,41 @@
Loading
3 3
// Inheritance
4 4
import "./Owned.sol";
5 5
import "./MixinResolver.sol";
6 -
import "./MixinSystemSettings.sol";
7 -
import "./interfaces/ISecondaryDeposit.sol";
6 +
import "./interfaces/ISynthetixBridgeToOptimism.sol";
8 7
9 8
// Internal references
10 9
import "./interfaces/ISynthetix.sol";
11 10
import "./interfaces/IERC20.sol";
12 11
import "./interfaces/IIssuer.sol";
13 -
import "./interfaces/IRewardEscrow.sol";
12 +
// import "./interfaces/IRewardEscrow.sol";
14 13
15 14
// solhint-disable indent
16 15
import "@eth-optimism/rollup-contracts/build/contracts/bridge/interfaces/CrossDomainMessenger.interface.sol";
17 16
18 17
19 -
contract SecondaryDeposit is Owned, MixinResolver, MixinSystemSettings, ISecondaryDeposit {
20 -
    bool public activated;
18 +
contract SynthetixBridgeToOptimism is Owned, MixinResolver, ISynthetixBridgeToOptimism {
19 +
    uint32 private constant CROSS_DOMAIN_MESSAGE_GAS_LIMIT = 3e6; //TODO: verify value, uint32 to uint in new version
21 20
22 21
    /* ========== ADDRESS RESOLVER CONFIGURATION ========== */
23 22
    bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
24 23
    bytes32 private constant CONTRACT_SYNTHETIX = "Synthetix";
25 24
    bytes32 private constant CONTRACT_ISSUER = "Issuer";
26 -
    bytes32 private constant CONTRACT_REWARDESCROW = "RewardEscrow";
27 -
    bytes32 private constant CONTRACT_ALT_SECONDARYDEPOSIT = "alt:SecondaryDeposit";
25 +
    // bytes32 private constant CONTRACT_REWARDESCROW = "RewardEscrow";
26 +
    bytes32 private constant CONTRACT_SYNTHETIX_BRIDGE_TO_BASE = "ovm:SynthetixBridgeToBase";
28 27
29 28
    bytes32[24] private addressesToCache = [
30 29
        CONTRACT_EXT_MESSENGER,
31 30
        CONTRACT_SYNTHETIX,
32 31
        CONTRACT_ISSUER,
33 -
        CONTRACT_REWARDESCROW,
34 -
        CONTRACT_ALT_SECONDARYDEPOSIT
32 +
        // CONTRACT_REWARDESCROW,
33 +
        CONTRACT_SYNTHETIX_BRIDGE_TO_BASE
35 34
    ];
36 35
37 -
    //
36 +
    bool public activated;
37 +
38 38
    // ========== CONSTRUCTOR ==========
39 39
40 -
    constructor(address _owner, address _resolver)
41 -
        public
42 -
        Owned(_owner)
43 -
        MixinResolver(_resolver, addressesToCache)
44 -
        MixinSystemSettings()
45 -
    {
40 +
    constructor(address _owner, address _resolver) public Owned(_owner) MixinResolver(_resolver, addressesToCache) {
46 41
        activated = true;
47 42
    }
48 43
@@ -70,14 +65,8 @@
Loading
70 65
    //     return IRewardEscrow(requireAndGetAddress(CONTRACT_REWARDESCROW, "Missing RewardEscrow address"));
71 66
    // }
72 67
73 -
    function companion() internal view returns (address) {
74 -
        return requireAndGetAddress(CONTRACT_ALT_SECONDARYDEPOSIT, "Missing Companion address");
75 -
    }
76 -
77 -
    /// ========= VIEWS =================
78 -
79 -
    function maximumDeposit() external view returns (uint) {
80 -
        return getMaximumDeposit();
68 +
    function synthetixBridgeToBase() internal view returns (address) {
69 +
        return requireAndGetAddress(CONTRACT_SYNTHETIX_BRIDGE_TO_BASE, "Missing Bridge address");
81 70
    }
82 71
83 72
    // ========== PUBLIC FUNCTIONS =========
@@ -86,8 +75,6 @@
Loading
86 75
    function deposit(uint amount) external {
87 76
        require(activated, "Function deactivated");
88 77
89 -
        require(amount <= getMaximumDeposit(), "Cannot deposit more than the max");
90 -
91 78
        require(issuer().debtBalanceOf(msg.sender, "sUSD") == 0, "Cannot deposit with debt");
92 79
93 80
        // now remove their reward escrow
@@ -100,73 +87,42 @@
Loading
100 87
        // create message payload for L2
101 88
        bytes memory messageData = abi.encodeWithSignature("mintSecondaryFromDeposit(address,uint256)", msg.sender, amount);
102 89
103 -
        // relay the message to this contract on L2 via Messenger1
104 -
        messenger().sendMessage(companion(), messageData, 3e6);
90 +
        // relay the message to this contract on L2 via L1 Messenger
91 +
        messenger().sendMessage(synthetixBridgeToBase(), messageData, CROSS_DOMAIN_MESSAGE_GAS_LIMIT);
105 92
106 93
        emit Deposit(msg.sender, amount);
107 94
    }
108 95
109 -
    // invoked by user on L2
110 -
    function initiateWithdrawal(
111 -
        uint /*amount*/
112 -
    ) external {
113 -
        revert("Not implemented");
114 -
115 -
        // instruct L2 Synthetix to burn this supply
116 -
        // synthetix().burnSecondary(msg.sender, amount);
117 -
118 -
        // // create message payload for L1
119 -
        // bytes memory messageData = abi.encodeWithSignature("completeWithdrawal(address,uint256)", msg.sender, amount);
120 -
121 -
        // // relay the message to SecondaryDepost on L1 via Messenger2
122 -
        // messenger().sendMessage(companion(), messageData, 3e6);
123 -
    }
124 -
125 96
    // ========= RESTRICTED FUNCTIONS ==============
126 97
127 -
    // invoked by Messenger2 on L2
128 -
    function mintSecondaryFromDeposit(address account, uint amount) external {
129 -
        // ensure function only callable from SecondaryDeposit1 via messenger (aka relayer)
98 +
    // invoked by Messenger on L1 after L2 waiting period elapses
99 +
    function completeWithdrawal(address account, uint amount) external {
100 +
        // ensure function only callable from L2 Bridge via messenger (aka relayer)
130 101
        require(msg.sender == address(messenger()), "Only the relayer can call this");
131 -
        require(messenger().xDomainMessageSender() == companion(), "Only deposit contract can invoke");
132 -
133 -
        // now tell Synthetix to mint these tokens, deposited in L1, into the same account for L2
134 -
        synthetix().mintSecondary(account, amount);
135 -
136 -
        emit MintedSecondary(account, amount);
137 -
    }
138 -
139 -
    // invoked by Messenger1 on L1 after L2 waiting period elapses
140 -
    function completeWithdrawal(
141 -
        address, /*account*/
142 -
        uint /*amount*/
143 -
    ) external {
144 -
        revert("Not implemented");
145 -
        // ensure function only callable from SecondaryDeposit2 via messenger (aka relayer)
146 -
        // require(msg.sender == address(messenger()), "Only the relayer can call this");
147 -
        // require(messenger().xDomainMessageSender() == companion(), "Only deposit contract can invoke");
102 +
        require(messenger().xDomainMessageSender() == synthetixBridgeToBase(), "Only the L2 bridge can invoke");
148 103
149 -
        // // transfer amount back to user
150 -
        // synthetixERC20().transfer(account, amount);
104 +
        // transfer amount back to user
105 +
        synthetixERC20().transfer(account, amount);
151 106
152 107
        // no escrow actions - escrow remains on L2
108 +
        emit WithdrawalCompleted(account, amount);
153 109
    }
154 110
155 111
    // invoked by the owner for migrating the contract to the new version that will allow for withdrawals
156 -
    function migrateDeposit(address newDeposit) external onlyOwner {
112 +
    function migrateBridge(address newBridge) external onlyOwner {
157 113
        activated = false;
158 114
159 115
        IERC20 ERC20Synthetix = synthetixERC20();
160 -
        // get the current contract balance and transfer it to the new SecondaryDeposit contract
116 +
        // get the current contract balance and transfer it to the new SynthetixL1ToL2Bridge contract
161 117
        uint contractBalance = ERC20Synthetix.balanceOf(address(this));
162 -
        ERC20Synthetix.transfer(newDeposit, contractBalance);
118 +
        ERC20Synthetix.transfer(newBridge, contractBalance);
163 119
164 -
        emit DepositMigrated(address(this), newDeposit, contractBalance);
120 +
        emit BridgeMigrated(address(this), newBridge, contractBalance);
165 121
    }
166 122
167 123
    // ========== EVENTS ==========
168 124
169 125
    event Deposit(address indexed account, uint amount);
170 -
    event DepositMigrated(address oldDeposit, address newDeposit, uint amount);
171 -
    event MintedSecondary(address indexed account, uint amount);
126 +
    event BridgeMigrated(address oldBridge, address newBridge, uint amount);
127 +
    event WithdrawalCompleted(address indexed account, uint amount);
172 128
}

@@ -22,7 +22,6 @@
Loading
22 22
    bytes32 internal constant SETTING_MINIMUM_STAKE_TIME = "minimumStakeTime";
23 23
    bytes32 internal constant SETTING_AGGREGATOR_WARNING_FLAGS = "aggregatorWarningFlags";
24 24
    bytes32 internal constant SETTING_TRADING_REWARDS_ENABLED = "tradingRewardsEnabled";
25 -
    bytes32 internal constant SETTING_MAXIMUM_DEPOSIT = "maximumDeposit";
26 25
    bytes32 internal constant SETTING_DEBT_SNAPSHOT_STALE_TIME = "debtSnapshotStaleTime";
27 26
28 27
    bytes32 private constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage";
@@ -94,10 +93,6 @@
Loading
94 93
        return flexibleStorage().getAddressValue(SETTING_CONTRACT_NAME, SETTING_AGGREGATOR_WARNING_FLAGS);
95 94
    }
96 95
97 -
    function getMaximumDeposit() internal view returns (uint) {
98 -
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_MAXIMUM_DEPOSIT);
99 -
    }
100 -
101 96
    function getDebtSnapshotStaleTime() internal view returns (uint) {
102 97
        return flexibleStorage().getUIntValue(SETTING_CONTRACT_NAME, SETTING_DEBT_SNAPSHOT_STALE_TIME);
103 98
    }
Files Coverage
contracts 98.18%
Project Totals (58 files) 98.18%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading