Skip to content

Commit dbd184a

Browse files
authored
Menkalinan release v2.54 (Synthetixio#1606)
1 parent 4aa8129 commit dbd184a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+6718
-1007
lines changed

.circleci/config.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ jobs:
4242
- attach_workspace:
4343
at: .
4444
- run: npx hardhat compile --optimizer --fail-oversize
45-
- run: rm -rf build # force a clean build
46-
- run: npx hardhat compile --use-ovm --optimizer --fail-oversize
4745
job-fork-tests:
4846
working_directory: ~/repo
4947
docker:
@@ -109,11 +107,11 @@ jobs:
109107
- run:
110108
name: Run isolated layer 2 integration tests
111109
command: |
112-
npx hardhat test:integration:l2 --compile --deploy || true # TEMP allow pass thru till PR #1598
110+
npx hardhat test:integration:l2 --compile --deploy
113111
- run:
114112
name: Run dual layer 1 and layer 2 integration tests
115113
command: |
116-
npx hardhat test:integration:dual --deploy || true # TEMP allow pass thru till PR #1598
114+
npx hardhat test:integration:dual --deploy
117115
job-lint:
118116
working_directory: ~/repo
119117
docker:

.circleci/src/jobs/job-compile.yml

-2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,3 @@ steps:
55
- attach_workspace:
66
at: .
77
- run: npx hardhat compile --optimizer --fail-oversize
8-
- run: rm -rf build # force a clean build
9-
- run: npx hardhat compile --use-ovm --optimizer --fail-oversize

.circleci/src/jobs/job-integration-tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ steps:
3838
- run:
3939
name: Run isolated layer 2 integration tests
4040
command: |
41-
npx hardhat test:integration:l2 --compile --deploy || true # TEMP allow pass thru till PR #1598
41+
npx hardhat test:integration:l2 --compile --deploy
4242
- run:
4343
name: Run dual layer 1 and layer 2 integration tests
4444
command: |
45-
npx hardhat test:integration:dual --deploy || true # TEMP allow pass thru till PR #1598
45+
npx hardhat test:integration:dual --deploy

.solcover.js

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ module.exports = {
1010
'legacy',
1111
'EscrowChecker.sol',
1212
'ExchangeRatesWithoutInvPricing.sol',
13-
'IssuerWithoutLiquidations.sol',
1413
'EmptyEtherWrapper.sol',
1514
],
1615
providerOptions: {

contracts/IssuerWithoutLiquidations.sol

-15
This file was deleted.

contracts/MixinSystemSettings.sol

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ contract MixinSystemSettings is MixinResolver {
2727
bytes32 internal constant SETTING_CROSS_DOMAIN_ESCROW_GAS_LIMIT = "crossDomainEscrowGasLimit";
2828
bytes32 internal constant SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT = "crossDomainRewardGasLimit";
2929
bytes32 internal constant SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT = "crossDomainWithdrawalGasLimit";
30+
bytes32 internal constant SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT = "crossDomainRelayGasLimit";
3031
bytes32 internal constant SETTING_ETHER_WRAPPER_MAX_ETH = "etherWrapperMaxETH";
3132
bytes32 internal constant SETTING_ETHER_WRAPPER_MINT_FEE_RATE = "etherWrapperMintFeeRate";
3233
bytes32 internal constant SETTING_ETHER_WRAPPER_BURN_FEE_RATE = "etherWrapperBurnFeeRate";
@@ -47,7 +48,7 @@ contract MixinSystemSettings is MixinResolver {
4748

4849
bytes32 internal constant CONTRACT_FLEXIBLESTORAGE = "FlexibleStorage";
4950

50-
enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal}
51+
enum CrossDomainMessageGasLimits {Deposit, Escrow, Reward, Withdrawal, Relay}
5152

5253
constructor(address _resolver) internal MixinResolver(_resolver) {}
5354

@@ -69,6 +70,8 @@ contract MixinSystemSettings is MixinResolver {
6970
return SETTING_CROSS_DOMAIN_REWARD_GAS_LIMIT;
7071
} else if (gasLimitType == CrossDomainMessageGasLimits.Withdrawal) {
7172
return SETTING_CROSS_DOMAIN_WITHDRAWAL_GAS_LIMIT;
73+
} else if (gasLimitType == CrossDomainMessageGasLimits.Relay) {
74+
return SETTING_CROSS_DOMAIN_RELAY_GAS_LIMIT;
7275
} else {
7376
revert("Unknown gas limit type");
7477
}

contracts/OwnerRelayOnEthereum.sol

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
pragma solidity ^0.5.16;
2+
pragma experimental ABIEncoderV2;
3+
4+
// Inheritance
5+
import "./Owned.sol";
6+
import "./MixinSystemSettings.sol";
7+
8+
// Internal references
9+
import "./interfaces/IOwnerRelayOnOptimism.sol";
10+
import "@eth-optimism/contracts/iOVM/bridge/messaging/iAbs_BaseCrossDomainMessenger.sol";
11+
12+
contract OwnerRelayOnEthereum is MixinSystemSettings, Owned {
13+
/* ========== ADDRESS RESOLVER CONFIGURATION ========== */
14+
15+
bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
16+
bytes32 private constant CONTRACT_OVM_OWNER_RELAY_ON_OPTIMISM = "ovm:OwnerRelayOnOptimism";
17+
18+
// ========== CONSTRUCTOR ==========
19+
20+
constructor(address _owner, address _resolver) public Owned(_owner) MixinSystemSettings(_resolver) {}
21+
22+
/* ========== INTERNALS ============ */
23+
24+
function _messenger() private view returns (iAbs_BaseCrossDomainMessenger) {
25+
return iAbs_BaseCrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER));
26+
}
27+
28+
function _ownerRelayOnOptimism() private view returns (address) {
29+
return requireAndGetAddress(CONTRACT_OVM_OWNER_RELAY_ON_OPTIMISM);
30+
}
31+
32+
function _getCrossDomainGasLimit(uint32 crossDomainGasLimit) private view returns (uint32) {
33+
// Use specified crossDomainGasLimit if specified value is not zero.
34+
// otherwise use the default in SystemSettings.
35+
return
36+
crossDomainGasLimit != 0
37+
? crossDomainGasLimit
38+
: uint32(getCrossDomainMessageGasLimit(CrossDomainMessageGasLimits.Relay));
39+
}
40+
41+
/* ========== VIEWS ========== */
42+
43+
function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
44+
bytes32[] memory existingAddresses = MixinSystemSettings.resolverAddressesRequired();
45+
bytes32[] memory newAddresses = new bytes32[](2);
46+
newAddresses[0] = CONTRACT_EXT_MESSENGER;
47+
newAddresses[1] = CONTRACT_OVM_OWNER_RELAY_ON_OPTIMISM;
48+
addresses = combineArrays(existingAddresses, newAddresses);
49+
}
50+
51+
/* ========== RESTRICTED ========== */
52+
53+
function initiateRelay(
54+
address target,
55+
bytes calldata payload,
56+
uint32 crossDomainGasLimit // If zero, uses default value in SystemSettings
57+
) external onlyOwner {
58+
IOwnerRelayOnOptimism ownerRelayOnOptimism;
59+
bytes memory messageData = abi.encodeWithSelector(ownerRelayOnOptimism.finalizeRelay.selector, target, payload);
60+
61+
_messenger().sendMessage(_ownerRelayOnOptimism(), messageData, _getCrossDomainGasLimit(crossDomainGasLimit));
62+
63+
emit RelayInitiated(target, payload);
64+
}
65+
66+
function initiateRelayBatch(
67+
address[] calldata targets,
68+
bytes[] calldata payloads,
69+
uint32 crossDomainGasLimit // If zero, uses default value in SystemSettings
70+
) external onlyOwner {
71+
// First check that the length of the arguments match
72+
require(targets.length == payloads.length, "Argument length mismatch");
73+
74+
IOwnerRelayOnOptimism ownerRelayOnOptimism;
75+
bytes memory messageData =
76+
abi.encodeWithSelector(ownerRelayOnOptimism.finalizeRelayBatch.selector, targets, payloads);
77+
78+
_messenger().sendMessage(_ownerRelayOnOptimism(), messageData, _getCrossDomainGasLimit(crossDomainGasLimit));
79+
80+
emit RelayBatchInitiated(targets, payloads);
81+
}
82+
83+
/* ========== EVENTS ========== */
84+
85+
event RelayInitiated(address target, bytes payload);
86+
event RelayBatchInitiated(address[] targets, bytes[] payloads);
87+
}

contracts/OwnerRelayOnOptimism.sol

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
pragma solidity ^0.5.16;
2+
pragma experimental ABIEncoderV2;
3+
4+
// Inheritance
5+
import "./MixinResolver.sol";
6+
import "./TemporarilyOwned.sol";
7+
import "./interfaces/IOwnerRelayOnOptimism.sol";
8+
9+
// Internal references
10+
import "@eth-optimism/contracts/iOVM/bridge/messaging/iAbs_BaseCrossDomainMessenger.sol";
11+
12+
contract OwnerRelayOnOptimism is MixinResolver, TemporarilyOwned, IOwnerRelayOnOptimism {
13+
/* ========== ADDRESS RESOLVER CONFIGURATION ========== */
14+
15+
bytes32 private constant CONTRACT_EXT_MESSENGER = "ext:Messenger";
16+
bytes32 private constant CONTRACT_BASE_OWNER_RELAY_ON_ETHEREUM = "base:OwnerRelayOnEthereum";
17+
18+
/* ========== CONSTRUCTOR ============ */
19+
20+
constructor(
21+
address _resolver,
22+
address _temporaryOwner,
23+
uint _ownershipDuration
24+
) public MixinResolver(_resolver) TemporarilyOwned(_temporaryOwner, _ownershipDuration) {}
25+
26+
/* ========== INTERNALS ============ */
27+
28+
function _messenger() private view returns (iAbs_BaseCrossDomainMessenger) {
29+
return iAbs_BaseCrossDomainMessenger(requireAndGetAddress(CONTRACT_EXT_MESSENGER));
30+
}
31+
32+
function _ownerRelayOnEthereum() private view returns (address) {
33+
return requireAndGetAddress(CONTRACT_BASE_OWNER_RELAY_ON_ETHEREUM);
34+
}
35+
36+
function _relayCall(address target, bytes memory payload) private {
37+
// solhint-disable avoid-low-level-calls
38+
(bool success, bytes memory result) = target.call(payload);
39+
40+
require(success, string(abi.encode("xChain call failed:", result)));
41+
}
42+
43+
function _onlyAllowMessengerAndL1Relayer() internal view {
44+
iAbs_BaseCrossDomainMessenger messenger = _messenger();
45+
46+
require(msg.sender == address(messenger), "Sender is not the messenger");
47+
require(messenger.xDomainMessageSender() == _ownerRelayOnEthereum(), "L1 sender is not the owner relay");
48+
}
49+
50+
modifier onlyMessengerAndL1Relayer() {
51+
_onlyAllowMessengerAndL1Relayer();
52+
_;
53+
}
54+
55+
/* ========== VIEWS ========== */
56+
57+
function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {
58+
addresses = new bytes32[](2);
59+
addresses[0] = CONTRACT_EXT_MESSENGER;
60+
addresses[1] = CONTRACT_BASE_OWNER_RELAY_ON_ETHEREUM;
61+
}
62+
63+
/* ========== EXTERNAL ========== */
64+
65+
function directRelay(address target, bytes calldata payload) external onlyTemporaryOwner {
66+
_relayCall(target, payload);
67+
68+
emit DirectRelay(target, payload);
69+
}
70+
71+
function finalizeRelay(address target, bytes calldata payload) external onlyMessengerAndL1Relayer {
72+
_relayCall(target, payload);
73+
74+
emit RelayFinalized(target, payload);
75+
}
76+
77+
function finalizeRelayBatch(address[] calldata targets, bytes[] calldata payloads) external onlyMessengerAndL1Relayer {
78+
for (uint256 i = 0; i < targets.length; i++) {
79+
_relayCall(targets[i], payloads[i]);
80+
}
81+
82+
emit RelayBatchFinalized(targets, payloads);
83+
}
84+
85+
/* ========== EVENTS ========== */
86+
87+
event DirectRelay(address target, bytes payload);
88+
event RelayFinalized(address target, bytes payload);
89+
event RelayBatchFinalized(address[] targets, bytes[] payloads);
90+
}

contracts/SynthetixBridgeEscrow.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "./Owned.sol";
55
import "./MixinResolver.sol";
66
import "./interfaces/ISynthetixBridgeEscrow.sol";
77

8-
// External references.
8+
// Internal references.
99
import "openzeppelin-solidity-2.3.0/contracts/token/ERC20/SafeERC20.sol";
1010

1111
contract SynthetixBridgeEscrow is Owned, ISynthetixBridgeEscrow {

contracts/TemporarilyOwned.sol

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
pragma solidity ^0.5.16;
2+
3+
contract TemporarilyOwned {
4+
address public temporaryOwner;
5+
address public nominatedOwner;
6+
uint public expiryTime;
7+
8+
constructor(address _temporaryOwner, uint _ownershipDuration) public {
9+
require(_temporaryOwner != address(0), "Temp owner address cannot be 0");
10+
require(_ownershipDuration > 0, "Duration cannot be 0");
11+
12+
temporaryOwner = _temporaryOwner;
13+
expiryTime = block.timestamp + _ownershipDuration;
14+
}
15+
16+
function setNewExpiryTime(uint _duration) external onlyTemporaryOwner {
17+
require(block.timestamp + _duration < expiryTime, "New expiry time must be sooner than it currently is");
18+
expiryTime = block.timestamp + _duration;
19+
}
20+
21+
function nominateNewOwner(address _owner) external onlyTemporaryOwner {
22+
nominatedOwner = _owner;
23+
emit OwnerNominated(_owner);
24+
}
25+
26+
function acceptOwnership() external {
27+
require(block.timestamp < expiryTime, "Ownership expired");
28+
require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
29+
emit OwnerChanged(temporaryOwner, nominatedOwner);
30+
temporaryOwner = nominatedOwner;
31+
nominatedOwner = address(0);
32+
}
33+
34+
modifier onlyTemporaryOwner {
35+
_onlyTemporaryOwner();
36+
_;
37+
}
38+
39+
function _onlyTemporaryOwner() private view {
40+
require(block.timestamp < expiryTime, "Ownership expired");
41+
require(msg.sender == temporaryOwner, "Only executable by temp owner");
42+
}
43+
44+
event OwnerNominated(address newOwner);
45+
event OwnerChanged(address oldOwner, address newOwner);
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pragma solidity >=0.4.24;
2+
pragma experimental ABIEncoderV2;
3+
4+
interface IOwnerRelayOnOptimism {
5+
function finalizeRelay(address target, bytes calldata payload) external;
6+
7+
function finalizeRelayBatch(address[] calldata target, bytes[] calldata payloads) external;
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pragma solidity ^0.5.16;
2+
3+
import "../TemporarilyOwned.sol";
4+
5+
contract TestableTempOwned is TemporarilyOwned {
6+
uint public testValue;
7+
8+
constructor(address _temporaryOwner, uint _ownershipDuration)
9+
public
10+
TemporarilyOwned(_temporaryOwner, _ownershipDuration)
11+
{}
12+
13+
function setTestValue(uint _testValue) external onlyTemporaryOwner {
14+
testValue = _testValue;
15+
}
16+
}

hardhat.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ module.exports = {
6464
outputFile: 'test-gas-used.log',
6565
},
6666
mocha: {
67-
timeout: 90e3, // 90s
67+
timeout: 120e3, // 120s
6868
},
6969
};

0 commit comments

Comments
 (0)