-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
236 changed files
with
37,529 additions
and
10,045 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// SPDX-License-Identifier: Apache-2.0. | ||
pragma solidity ^0.6.12; | ||
|
||
/** | ||
Interface for contract initialization. | ||
The functions it exposes are the app specific parts of the contract initialization, | ||
and are called by the ProxySupport contract that implement the generic part of behind-proxy | ||
initialization. | ||
*/ | ||
abstract contract ContractInitializer { | ||
function numOfSubContracts() internal pure virtual returns (uint256); | ||
|
||
function isInitialized() internal view virtual returns (bool); | ||
|
||
function validateInitData(bytes calldata data) internal pure virtual; | ||
|
||
function processSubContractAddresses(bytes calldata subContractAddresses) internal virtual; | ||
|
||
function initializeContractState(bytes calldata data) internal virtual; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../scalable-dex/contracts/src/interfaces/ExternalInitializer.sol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// SPDX-License-Identifier: Apache-2.0. | ||
pragma solidity ^0.6.12; | ||
|
||
import "../components/Governance.sol"; | ||
import "../libraries/Common.sol"; | ||
import "./BlockDirectCall.sol"; | ||
import "./ContractInitializer.sol"; | ||
|
||
/** | ||
This contract contains the code commonly needed for a contract to be deployed behind | ||
an upgradability proxy. | ||
It perform the required semantics of the proxy pattern, | ||
but in a generic manner. | ||
Instantiation of the Governance and of the ContractInitializer, that are the app specific | ||
part of initialization, has to be done by the using contract. | ||
*/ | ||
abstract contract ProxySupport is Governance, BlockDirectCall, ContractInitializer { | ||
using Addresses for address; | ||
|
||
// The two function below (isFrozen & initialize) needed to bind to the Proxy. | ||
function isFrozen() external view virtual returns (bool) { | ||
return false; | ||
} | ||
|
||
/* | ||
The initialize() function serves as an alternative constructor for a proxied deployment. | ||
Flow and notes: | ||
1. This function cannot be called directly on the deployed contract, but only via | ||
delegate call. | ||
2. If an EIC is provided - init is passed onto EIC and the standard init flow is skipped. | ||
This true for both first intialization or a later one. | ||
3. The data passed to this function is as follows: | ||
[sub_contracts addresses, eic address, initData]. | ||
When calling on an initialized contract (no EIC scenario), initData.length must be 0. | ||
*/ | ||
function initialize(bytes calldata data) external notCalledDirectly { | ||
uint256 eicOffset = 32 * numOfSubContracts(); | ||
uint256 expectedBaseSize = eicOffset + 32; | ||
require(data.length >= expectedBaseSize, "INIT_DATA_TOO_SMALL"); | ||
address eicAddress = abi.decode(data[eicOffset:expectedBaseSize], (address)); | ||
|
||
bytes calldata subContractAddresses = data[:eicOffset]; | ||
|
||
processSubContractAddresses(subContractAddresses); | ||
|
||
bytes calldata initData = data[expectedBaseSize:]; | ||
|
||
// EIC Provided - Pass initData to EIC and the skip standard init flow. | ||
if (eicAddress != address(0x0)) { | ||
callExternalInitializer(eicAddress, initData); | ||
return; | ||
} | ||
|
||
if (isInitialized()) { | ||
require(initData.length == 0, "UNEXPECTED_INIT_DATA"); | ||
} else { | ||
// Contract was not initialized yet. | ||
validateInitData(initData); | ||
initializeContractState(initData); | ||
initGovernance(); | ||
} | ||
} | ||
|
||
function callExternalInitializer(address externalInitializerAddr, bytes calldata eicData) | ||
private | ||
{ | ||
require(externalInitializerAddr.isContract(), "EIC_NOT_A_CONTRACT"); | ||
|
||
// NOLINTNEXTLINE: low-level-calls, controlled-delegatecall. | ||
(bool success, bytes memory returndata) = externalInitializerAddr.delegatecall( | ||
abi.encodeWithSelector(this.initialize.selector, eicData) | ||
); | ||
require(success, string(returndata)); | ||
require(returndata.length == 0, string(returndata)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: Apache-2.0. | ||
pragma solidity ^0.6.12; | ||
|
||
/* | ||
Library to provide basic storage, in storage location out of the low linear address space. | ||
New types of storage variables should be added here upon need. | ||
*/ | ||
library NamedStorage { | ||
function bytes32ToUint256Mapping(string memory tag_) | ||
internal | ||
pure | ||
returns (mapping(bytes32 => uint256) storage randomVariable) | ||
{ | ||
bytes32 location = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
randomVariable_slot := location | ||
} | ||
} | ||
|
||
function bytes32ToAddressMapping(string memory tag_) | ||
internal | ||
pure | ||
returns (mapping(bytes32 => address) storage randomVariable) | ||
{ | ||
bytes32 location = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
randomVariable_slot := location | ||
} | ||
} | ||
|
||
function uintToAddressMapping(string memory tag_) | ||
internal | ||
pure | ||
returns (mapping(uint256 => address) storage randomVariable) | ||
{ | ||
bytes32 location = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
randomVariable_slot := location | ||
} | ||
} | ||
|
||
function addressToBoolMapping(string memory tag_) | ||
internal | ||
pure | ||
returns (mapping(address => bool) storage randomVariable) | ||
{ | ||
bytes32 location = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
randomVariable_slot := location | ||
} | ||
} | ||
|
||
function getUintValue(string memory tag_) internal view returns (uint256 retVal) { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
retVal := sload(slot) | ||
} | ||
} | ||
|
||
function setUintValue(string memory tag_, uint256 value) internal { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
sstore(slot, value) | ||
} | ||
} | ||
|
||
function setUintValueOnce(string memory tag_, uint256 value) internal { | ||
require(getUintValue(tag_) == 0, "ALREADY_SET"); | ||
setUintValue(tag_, value); | ||
} | ||
|
||
function getAddressValue(string memory tag_) internal view returns (address retVal) { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
retVal := sload(slot) | ||
} | ||
} | ||
|
||
function setAddressValue(string memory tag_, address value) internal { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
sstore(slot, value) | ||
} | ||
} | ||
|
||
function setAddressValueOnce(string memory tag_, address value) internal { | ||
require(getAddressValue(tag_) == address(0x0), "ALREADY_SET"); | ||
setAddressValue(tag_, value); | ||
} | ||
|
||
function getBoolValue(string memory tag_) internal view returns (bool retVal) { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
retVal := sload(slot) | ||
} | ||
} | ||
|
||
function setBoolValue(string memory tag_, bool value) internal { | ||
bytes32 slot = keccak256(abi.encodePacked(tag_)); | ||
assembly { | ||
sstore(slot, value) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.