diff --git a/contracts/BondDepository.sol b/contracts/BondDepository.sol index b51c698..31b1daa 100644 --- a/contracts/BondDepository.sol +++ b/contracts/BondDepository.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + interface IOwnable { function policy() external view returns (address); @@ -11,7 +68,7 @@ interface IOwnable { function pullManagement() external; } -contract Ownable is IOwnable { +contract Ownable is IOwnable, Initializable { address internal _owner; address internal _newOwner; @@ -19,7 +76,16 @@ contract Ownable is IOwnable { event OwnershipPushed(address indexed previousOwner, address indexed newOwner); event OwnershipPulled(address indexed previousOwner, address indexed newOwner); - constructor () { + // constructor () { + // _owner = msg.sender; + // emit OwnershipPushed( address(0), _owner ); + // } + + function __Ownable_initialize() internal initializer { + __Ownable_init_unchain(); + } + + function __Ownable_init_unchain() internal initializer { _owner = msg.sender; emit OwnershipPushed( address(0), _owner ); } @@ -623,13 +689,13 @@ contract SynassetsBondDepository is Ownable { /* ======== STATE VARIABLES ======== */ - address public immutable SYNASSETS; // token given as payment for bond - address public immutable principle; // token used to create bond - address public immutable treasury; // mints SYNASSETS when receives principle - address public immutable DAO; // receives profit share from bond + address public SYNASSETS; // token given as payment for bond + address public principle; // token used to create bond + address public treasury; // mints SYNASSETS when receives principle + address public DAO; // receives profit share from bond - bool public immutable isLiquidityBond; // LP and Reserve bonds are treated slightly different - address public immutable bondCalculator; // calculates value of LP tokens + bool public isLiquidityBond; // LP and Reserve bonds are treated slightly different + address public bondCalculator; // calculates value of LP tokens address public staking; // to auto-stake payout address public stakingHelper; // to stake and claim if no staking warmup @@ -681,13 +747,53 @@ contract SynassetsBondDepository is Ownable { /* ======== INITIALIZATION ======== */ - constructor ( +// constructor ( +// address _SYNASSETS, +// address _principle, +// address _treasury, +// address _DAO, +// address _bondCalculator +// ) { +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// require( _principle != address(0) ); +// principle = _principle; +// require( _treasury != address(0) ); +// treasury = _treasury; +// require( _DAO != address(0) ); +// DAO = _DAO; +// // bondCalculator should be address(0) if not LP bond +// bondCalculator = _bondCalculator; +// isLiquidityBond = ( _bondCalculator != address(0) ); +// } + + function __SynassetsBondDepository_initialize( + address _SYNASSETS, + address _principle, + address _treasury, + address _DAO, + address _bondCalculator + ) external initializer { + __SynassetsBondDepository_init_unchain(_SYNASSETS, _principle, _treasury, _DAO, _bondCalculator); + } + + function __setParameters( + address _SYNASSETS, + address _principle, + address _treasury, + address _DAO, + address _bondCalculator + ) external onlyPolicy { + __SynassetsBondDepository_init_unchain(_SYNASSETS, _principle, _treasury, _DAO, _bondCalculator); + } + + function __SynassetsBondDepository_init_unchain( address _SYNASSETS, address _principle, address _treasury, address _DAO, address _bondCalculator - ) { + ) internal { require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; require( _principle != address(0) ); diff --git a/contracts/ConsensusPool.sol b/contracts/ConsensusPool.sol index d6f6c68..8fe3cb4 100644 --- a/contracts/ConsensusPool.sol +++ b/contracts/ConsensusPool.sol @@ -1,6 +1,112 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + +interface IOwnable { + function owner() external view returns (address); + + function renounceOwnership() external; + + function transferOwnership( address newOwner_ ) external; +} + +contract Ownable is IOwnable, Initializable { + + address internal _owner; + address internal _pendingOwner; + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event OwnershipTransferring(address indexed owner, address indexed pendingOwner); + + function __Ownable_init_unchain() internal initializer { + require(_owner == address(0)); + _owner = msg.sender; + emit OwnershipTransferred( address(0), _owner ); + } + + function owner() public view override returns (address) { + return _owner; + } + + modifier onlyOwner() { + require( _owner == msg.sender, "Ownable: caller is not the owner" ); + _; + } + + function renounceOwnership() public virtual override onlyOwner() { + emit OwnershipTransferred( _owner, address(0) ); + _owner = address(0); + } + + function transferOwnership( address newOwner_ ) public virtual override onlyOwner() { + require( newOwner_ != address(0), "Ownable: new owner is the zero address"); + emit OwnershipTransferring( _owner, newOwner_ ); + _pendingOwner = newOwner_; + } + + function acceptOwnership() external { + require(_pendingOwner == msg.sender, "Permission denied"); + emit OwnershipTransferred( _owner, msg.sender ); + _owner = msg.sender; + } +} + library LowGasSafeMath { /// @notice Returns x + y, reverts if sum overflows uint256 /// @param x The augend @@ -173,7 +279,7 @@ interface IDistributor { } // 7.97% -contract ConsensusPool { +contract ConsensusPool is Ownable { using LowGasSafeMath for uint256; using SafeERC20 for IERC20; @@ -234,7 +340,32 @@ contract ConsensusPool { event Unstaked(address indexed unstaker, address indexed inviter, uint256 amount); event RewardPaid(address indexed user, uint256 reward); - function initialize ( + function __ConsensusPool_initialize ( + address _SYNASSETS, + address _sSYNASSETS, + uint256 _epochLength, + uint256 _firstEpochNumber, + uint256 _firstEpochBlock, + address _stakingContract, + address _distributor + ) external initializer { + __ConsensusPool_init_unchain(_SYNASSETS, _sSYNASSETS, _epochLength, _firstEpochNumber, _firstEpochBlock, _stakingContract, _distributor); + __Ownable_init_unchain(); + } + + function setParameter( + address _SYNASSETS, + address _sSYNASSETS, + uint256 _epochLength, + uint256 _firstEpochNumber, + uint256 _firstEpochBlock, + address _stakingContract, + address _distributor + ) external onlyOwner { + __ConsensusPool_init_unchain(_SYNASSETS, _sSYNASSETS, _epochLength, _firstEpochNumber, _firstEpochBlock, _stakingContract, _distributor); + } + + function __ConsensusPool_init_unchain( address _SYNASSETS, address _sSYNASSETS, uint256 _epochLength, @@ -242,8 +373,8 @@ contract ConsensusPool { uint256 _firstEpochBlock, address _stakingContract, address _distributor - ) external { - require( SYNASSETS == address(0), 'AI' ); + ) internal { +// require( SYNASSETS == address(0), 'AI' ); require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; @@ -256,7 +387,7 @@ contract ConsensusPool { number: _firstEpochNumber, endBlock: _firstEpochBlock, distribute: 0 - }); + }); stakingContract = _stakingContract; distributor = _distributor; diff --git a/contracts/SATTimelock.sol b/contracts/SATTimelock.sol index e00d4f9..facbeab 100644 --- a/contracts/SATTimelock.sol +++ b/contracts/SATTimelock.sol @@ -620,7 +620,7 @@ contract SATTimelock is Ownable { IERC20(token).safeTransfer(claimAddress, unlocked_); } - function increaseReward() external { + function increaseReward() public { uint256 balance_ = IERC20(token).balanceOf(address(this)); uint256 amount_ = balance_.sub(reserveToken); diff --git a/contracts/Staking.sol b/contracts/Staking.sol index 085a15e..cb0d4e5 100644 --- a/contracts/Staking.sol +++ b/contracts/Staking.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on @@ -475,7 +532,7 @@ interface IOwnable { function pullManagement() external; } -contract Ownable is IOwnable { +contract Ownable is IOwnable, Initializable { address internal _owner; address internal _newOwner; @@ -483,7 +540,16 @@ contract Ownable is IOwnable { event OwnershipPushed(address indexed previousOwner, address indexed newOwner); event OwnershipPulled(address indexed previousOwner, address indexed newOwner); - constructor () { + // constructor () { + // _owner = msg.sender; + // emit OwnershipPushed( address(0), _owner ); + // } + + function __Ownable_initialize() internal initializer { + __Ownable_init_unchain(); + } + + function __Ownable_init_unchain() internal initializer { _owner = msg.sender; emit OwnershipPushed( address(0), _owner ); } @@ -547,8 +613,8 @@ contract SynassetsStaking is Ownable { using SafeMath for uint256; using SafeERC20 for IERC20; - address public immutable SYNASSETS; - address public immutable sSYNASSETS; + address public SYNASSETS; + address public sSYNASSETS; struct Epoch { uint length; @@ -568,13 +634,54 @@ contract SynassetsStaking is Ownable { address public consensusPool; - constructor ( +// constructor ( +// address _SYNASSETS, +// address _sSYNASSETS, +// uint _epochLength, +// uint _firstEpochNumber, +// uint _firstEpochBlock +// ) { +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// require( _sSYNASSETS != address(0) ); +// sSYNASSETS = _sSYNASSETS; +// +// epoch = Epoch({ +// length: _epochLength, +// number: _firstEpochNumber, +// endBlock: _firstEpochBlock, +// distribute: 0 +// }); +// } + + function __SynassetsStaking_initialize( + address _SYNASSETS, + address _sSYNASSETS, + uint _epochLength, + uint _firstEpochNumber, + uint _firstEpochBlock + ) external initializer { + __SynassetsStaking_init_unchain(_SYNASSETS, _sSYNASSETS, _epochLength, _firstEpochNumber, _firstEpochBlock); + __Ownable_initialize(); + } + + function setParameter( + address _SYNASSETS, + address _sSYNASSETS, + uint _epochLength, + uint _firstEpochNumber, + uint _firstEpochBlock + ) external onlyManager { + __SynassetsStaking_init_unchain(_SYNASSETS, _sSYNASSETS, _epochLength, _firstEpochNumber, _firstEpochBlock); + } + + function __SynassetsStaking_init_unchain( address _SYNASSETS, address _sSYNASSETS, uint _epochLength, uint _firstEpochNumber, uint _firstEpochBlock - ) { + ) internal { require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; require( _sSYNASSETS != address(0) ); diff --git a/contracts/StakingDistributor.sol b/contracts/StakingDistributor.sol index fea3326..49d342f 100644 --- a/contracts/StakingDistributor.sol +++ b/contracts/StakingDistributor.sol @@ -2,6 +2,63 @@ pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + library SafeERC20 { using SafeMath for uint256; using Address for address; @@ -286,14 +343,23 @@ interface IPolicy { function pullPolicy() external; } -contract Policy is IPolicy { +contract Policy is IPolicy, Initializable { address internal _policy; address internal _newPolicy; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - constructor () { +// constructor () { +// _policy = msg.sender; +// emit OwnershipTransferred( address(0), _policy ); +// } + + function __Policy_initialize() internal initializer { + __Policy_init_unchain(); + } + + function __Policy_init_unchain() internal initializer { _policy = msg.sender; emit OwnershipTransferred( address(0), _policy ); } @@ -336,10 +402,10 @@ contract Distributor is Policy { /* ====== VARIABLES ====== */ - address public immutable SYNASSETS; - address public immutable treasury; + address public SYNASSETS; + address public treasury; - uint public immutable epochLength; + uint public epochLength; uint public nextEpochBlock; mapping( uint => Adjust ) public adjustments; @@ -363,7 +429,25 @@ contract Distributor is Policy { /* ====== CONSTRUCTOR ====== */ - constructor( address _treasury, address _SYNASSETS, uint _epochLength, uint _nextEpochBlock ) { +// constructor( address _treasury, address _SYNASSETS, uint _epochLength, uint _nextEpochBlock ) { +// require( _treasury != address(0) ); +// treasury = _treasury; +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// epochLength = _epochLength; +// nextEpochBlock = _nextEpochBlock; +// } + + function __Distributor_initialize( address _treasury, address _SYNASSETS, uint _epochLength, uint _nextEpochBlock ) external initializer { + __Distributor_init_unchain(_treasury, _SYNASSETS, _epochLength, _nextEpochBlock); + __Policy_initialize(); + } + + function setParameters( address _treasury, address _SYNASSETS, uint _epochLength, uint _nextEpochBlock ) onlyPolicy external { + __Distributor_init_unchain(_treasury, _SYNASSETS, _epochLength, _nextEpochBlock); + } + + function __Distributor_init_unchain( address _treasury, address _SYNASSETS, uint _epochLength, uint _nextEpochBlock ) internal { require( _treasury != address(0) ); treasury = _treasury; require( _SYNASSETS != address(0) ); diff --git a/contracts/StakingHelper.sol b/contracts/StakingHelper.sol index 97b7c22..5229865 100644 --- a/contracts/StakingHelper.sol +++ b/contracts/StakingHelper.sol @@ -10,6 +10,63 @@ pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + interface IERC20 { function decimals() external view returns (uint8); /** @@ -87,12 +144,23 @@ interface IStaking { function claim( address _recipient, address inviter ) external; } -contract StakingHelper { +contract StakingHelper is Initializable { + + address public staking; + address public SYNASSETS; - address public immutable staking; - address public immutable SYNASSETS; +// constructor ( address _staking, address _SYNASSETS ) { +// require( _staking != address(0) ); +// staking = _staking; +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// } + + function __StakingHelper_initialize( address _staking, address _SYNASSETS ) external initializer { + __StakingHelper_init_unchain(_staking, _SYNASSETS); + } - constructor ( address _staking, address _SYNASSETS ) { + function __StakingHelper_init_unchain( address _staking, address _SYNASSETS ) internal initializer { require( _staking != address(0) ); staking = _staking; require( _SYNASSETS != address(0) ); diff --git a/contracts/StakingWarmup.sol b/contracts/StakingWarmup.sol index ff3c919..ca8ccf6 100644 --- a/contracts/StakingWarmup.sol +++ b/contracts/StakingWarmup.sol @@ -1,6 +1,62 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} interface IERC20 { function decimals() external view returns (uint8); @@ -74,12 +130,23 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -contract StakingWarmup { +contract StakingWarmup is Initializable { + + address public staking; + address public sSYNASSETS; - address public immutable staking; - address public immutable sSYNASSETS; +// constructor ( address _staking, address _sSYNASSETS ) { +// require( _staking != address(0) ); +// staking = _staking; +// require( _sSYNASSETS != address(0) ); +// sSYNASSETS = _sSYNASSETS; +// } + + function __StakingWarmup_initialize( address _staking, address _sSYNASSETS ) external initializer { + __StakingWarmup_init_unchain(_staking, _sSYNASSETS); + } - constructor ( address _staking, address _sSYNASSETS ) { + function __StakingWarmup_init_unchain( address _staking, address _sSYNASSETS ) internal initializer { require( _staking != address(0) ); staking = _staking; require( _sSYNASSETS != address(0) ); diff --git a/contracts/StandardBondingCalculator.sol b/contracts/StandardBondingCalculator.sol index 3afe932..61a7503 100644 --- a/contracts/StandardBondingCalculator.sol +++ b/contracts/StandardBondingCalculator.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + library FullMath { function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) { uint256 mm = mulmod(x, y, uint256(-1)); @@ -259,15 +316,24 @@ interface IBondingCalculator { function valuation( address pair_, uint amount_ ) external view returns ( uint _value ); } -contract SynassetsBondingCalculator is IBondingCalculator { +contract SynassetsBondingCalculator is IBondingCalculator, Initializable { using FixedPoint for *; using SafeMath for uint; using SafeMath for uint112; - address public immutable SYNASSETS; + address public SYNASSETS; + +// constructor( address _SYNASSETS ) { +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// } + + function __SynassetsBondingCalculator_initialize( address _SYNASSETS ) external initializer { + __SynassetsBondingCalculator_unchain(_SYNASSETS); + } - constructor( address _SYNASSETS ) { + function __SynassetsBondingCalculator_unchain( address _SYNASSETS ) internal initializer { require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; } diff --git a/contracts/SynassetsERC20.sol b/contracts/SynassetsERC20.sol index c408c72..0d541bd 100644 --- a/contracts/SynassetsERC20.sol +++ b/contracts/SynassetsERC20.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + library EnumerableSet { // To implement this library for multiple types with as little code @@ -597,7 +654,7 @@ library SafeMath { } } -abstract contract ERC20 is IERC20 { +abstract contract ERC20 is IERC20, Initializable { using SafeMath for uint256; @@ -622,7 +679,17 @@ abstract contract ERC20 is IERC20 { // Present in ERC777 uint8 internal _decimals; - constructor (string memory name_, string memory symbol_, uint8 decimals_) { +// constructor (string memory name_, string memory symbol_, uint8 decimals_) { +// _name = name_; +// _symbol = symbol_; +// _decimals = decimals_; +// } + + function __ERC20_initialize(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { + __ERC20_init_unchain(name_, symbol_, decimals_); + } + + function __ERC20_init_unchain(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { _name = name_; _symbol = symbol_; _decimals = decimals_; @@ -763,21 +830,40 @@ abstract contract ERC20Permit is ERC20, IERC2612Permit { bytes32 public DOMAIN_SEPARATOR; - constructor() { +// constructor() { +// +// uint256 chainID; +// assembly { +// chainID := chainid() +// } +// +// DOMAIN_SEPARATOR = keccak256(abi.encode( +// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), +// keccak256(bytes(name())), +// keccak256(bytes("1")), // Version +// chainID, +// address(this) +// )); +// } + + function __ERC20Permit_initialize(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { + __ERC20Permit_init_unchain(); + __ERC20_initialize(name_, symbol_, decimals_); + } + + function __ERC20Permit_init_unchain() internal initializer { uint256 chainID; assembly { chainID := chainid() } - DOMAIN_SEPARATOR = keccak256( - abi.encode( + DOMAIN_SEPARATOR = keccak256(abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name())), keccak256(bytes("1")), // Version chainID, address(this) - ) - ); + )); } function permit( @@ -816,13 +902,22 @@ interface IOwnable { function transferOwnership( address newOwner_ ) external; } -contract Ownable is IOwnable { +contract Ownable is IOwnable, Initializable { address internal _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - constructor () { +// constructor () { +// _owner = msg.sender; +// emit OwnershipTransferred( address(0), _owner ); +// } + + function __Ownable_initialize() internal initializer { + __Ownable_init_unchain(); + } + + function __Ownable_init_unchain() internal initializer { _owner = msg.sender; emit OwnershipTransferred( address(0), _owner ); } @@ -852,6 +947,13 @@ contract VaultOwned is Ownable { address internal _vault; + function __VaultOwned_initialize() internal initializer { + __VaultOwned_init_unchain(); + __Ownable_init_unchain(); + } + + function __VaultOwned_init_unchain() internal initializer { } + function setVault( address vault_ ) external onlyOwner() returns ( bool ) { _vault = vault_; @@ -1097,9 +1199,9 @@ contract SynassetsERC20Token is ERC20Permit, VaultOwned { mapping (address => bool) private _isExcludedFromFee; address private _vaultTmpAddress; - address public immutable uniswapV2Pair; - IUniswapV2Router02 public immutable uniswapV2Router; - IERC20 public immutable assetToken; + address public uniswapV2Pair; + IUniswapV2Router02 public uniswapV2Router; + IERC20 public assetToken; event SwapAndLiquify( uint256 tokensSwapped, @@ -1113,7 +1215,26 @@ contract SynassetsERC20Token is ERC20Permit, VaultOwned { inSwapAndLiquify = false; } - constructor(IUniswapV2Router02 _uniswapV2Router, IERC20 _assetToken) ERC20("Synassets Token", "SYNASSETS", 9) { +// constructor(IUniswapV2Router02 _uniswapV2Router, IERC20 _assetToken) ERC20("Synassets Token", "SYNASSETS", 9) { +// uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), address(_assetToken)); +// uniswapV2Router = _uniswapV2Router; +// assetToken = _assetToken; +// +// _isExcludedFromFee[msg.sender] = true; +// _isExcludedFromFee[address(this)] = true; +// } + + function __SynassetsERC20Token_initialize(IUniswapV2Router02 _uniswapV2Router, IERC20 _assetToken) external initializer { + __SynassetsERC20Token_unchain(_uniswapV2Router, _assetToken); + __VaultOwned_initialize(); + __ERC20Permit_initialize("Synassets Token", "SYNASSETS", 9); + } + + function setParameter(IUniswapV2Router02 _uniswapV2Router, IERC20 _assetToken) external onlyVault { + __SynassetsERC20Token_unchain(_uniswapV2Router, _assetToken); + } + + function __SynassetsERC20Token_unchain(IUniswapV2Router02 _uniswapV2Router, IERC20 _assetToken) internal { uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), address(_assetToken)); uniswapV2Router = _uniswapV2Router; assetToken = _assetToken; diff --git a/contracts/Treasury.sol b/contracts/Treasury.sol index 4993bcd..7943f86 100644 --- a/contracts/Treasury.sol +++ b/contracts/Treasury.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { @@ -107,7 +164,7 @@ interface IOwnable { function pullManagement() external; } -contract Ownable is IOwnable { +contract Ownable is IOwnable, Initializable { address internal _owner; address internal _newOwner; @@ -115,7 +172,16 @@ contract Ownable is IOwnable { event OwnershipPushed(address indexed previousOwner, address indexed newOwner); event OwnershipPulled(address indexed previousOwner, address indexed newOwner); - constructor () { + // constructor () { + // _owner = msg.sender; + // emit OwnershipPushed( address(0), _owner ); + // } + + function __Ownable_initialize() internal initializer { + __Ownable_init_unchain(); + } + + function __Ownable_init_unchain() internal initializer { _owner = msg.sender; emit OwnershipPushed( address(0), _owner ); } @@ -218,8 +284,8 @@ contract SynassetsTreasury is Ownable { enum MANAGING { RESERVEDEPOSITOR, RESERVESPENDER, RESERVETOKEN, RESERVEMANAGER, LIQUIDITYDEPOSITOR, LIQUIDITYTOKEN, LIQUIDITYMANAGER, DEBTOR, REWARDMANAGER, SSYNASSETS } - address public immutable SYNASSETS; - uint public immutable blocksNeededForQueue; + address public SYNASSETS; + uint public blocksNeededForQueue; address[] public reserveTokens; // Push only, beware false-positives. mapping( address => bool ) public isReserveToken; @@ -266,11 +332,34 @@ contract SynassetsTreasury is Ownable { uint public totalReserves; // Risk-free value of all assets uint public totalDebt; - constructor ( +// constructor ( +// address _SYNASSETS, +// address _ASSET, +// uint _blocksNeededForQueue +// ) { +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// +// isReserveToken[ _ASSET ] = true; +// reserveTokens.push( _ASSET ); +// +// blocksNeededForQueue = _blocksNeededForQueue; +// } + + function __SynassetsTreasury_initialize( + address _SYNASSETS, + address _ASSET, + uint _blocksNeededForQueue + ) external initializer { + __SynassetsTreasury_unchain(_SYNASSETS, _ASSET, _blocksNeededForQueue); + __Ownable_initialize(); + } + + function __SynassetsTreasury_unchain( address _SYNASSETS, address _ASSET, uint _blocksNeededForQueue - ) { + ) internal initializer { require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; diff --git a/contracts/VaultTmp.sol b/contracts/VaultTmp.sol index afee763..919580a 100644 --- a/contracts/VaultTmp.sol +++ b/contracts/VaultTmp.sol @@ -1,6 +1,63 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} + interface IERC20 { /** * @dev Returns the amount of tokens in existence. @@ -72,11 +129,20 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -contract VaultTmp { +contract VaultTmp is Initializable { + + address public SYNASSETS; - address public immutable SYNASSETS; +// constructor ( address _SYNASSETS ) { +// require( _SYNASSETS != address(0) ); +// SYNASSETS = _SYNASSETS; +// } + + function __VaultTmp_initialize( address _SYNASSETS ) external initializer { + __VaultTmp_init_unchain(_SYNASSETS); + } - constructor ( address _SYNASSETS ) { + function __VaultTmp_init_unchain( address _SYNASSETS ) internal initializer { require( _SYNASSETS != address(0) ); SYNASSETS = _SYNASSETS; } diff --git a/contracts/sSynassetsERC20.sol b/contracts/sSynassetsERC20.sol index 943bbd8..4e44f6f 100644 --- a/contracts/sSynassetsERC20.sol +++ b/contracts/sSynassetsERC20.sol @@ -1,6 +1,62 @@ // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; +/** + * @title Initializable + * + * @dev Helper contract to support initializer functions. To use it, replace + * the constructor with a function that has the `initializer` modifier. + * WARNING: Unlike constructors, initializer functions must be manually + * invoked. This applies both to deploying an Initializable contract, as well + * as extending an Initializable contract via inheritance. + * WARNING: When used with inheritance, manual care must be taken to not invoke + * a parent initializer twice, or ensure that all initializers are idempotent, + * because this is not dealt with automatically as with constructors. + */ +contract Initializable { + + /** + * @dev Indicates that the contract has been initialized. + */ + bool private initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private initializing; + + /** + * @dev Modifier to use in the initializer function of a contract. + */ + modifier initializer() { + require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); + + bool isTopLevelCall = !initializing; + if (isTopLevelCall) { + initializing = true; + initialized = true; + } + + _; + + if (isTopLevelCall) { + initializing = false; + } + } + + /// @dev Returns true if and only if the function is running in the constructor + function isConstructor() private view returns (bool) { + // extcodesize checks the size of the code stored in an address, and + // address returns the current address. Since the code is still not + // deployed when running a constructor, any checks on its code size will + // yield zero, making it an effective way to detect if a contract is + // under construction or not. + address self = address(this); + uint256 cs; + assembly { cs := extcodesize(self) } + return cs == 0; + } +} /** * @dev Wrappers over Solidity's arithmetic operations with added overflow @@ -508,7 +564,7 @@ interface IERC20 { abstract contract ERC20 is - IERC20 + IERC20, Initializable { using SafeMath for uint256; @@ -543,10 +599,20 @@ abstract contract ERC20 * All three of these values are immutable: they can only be set once during * construction. */ - constructor (string memory name_, string memory symbol_, uint8 decimals_) { - _name = name_; - _symbol = symbol_; - _decimals = decimals_; +// constructor (string memory name_, string memory symbol_, uint8 decimals_) { +// _name = name_; +// _symbol = symbol_; +// _decimals = decimals_; +// } + + function __ERC20_initialize(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { + __ERC20_init_unchain(name_, symbol_, decimals_); + } + + function __ERC20_init_unchain(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { + _name = name_; + _symbol = symbol_; + _decimals = decimals_; } /** @@ -886,20 +952,40 @@ abstract contract ERC20Permit is ERC20, IERC2612Permit { bytes32 public DOMAIN_SEPARATOR; - constructor() { - +// constructor() { +// +// uint256 chainID; +// assembly { +// chainID := chainid() +// } +// +// DOMAIN_SEPARATOR = keccak256(abi.encode( +// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), +// keccak256(bytes(name())), +// keccak256(bytes("1")), // Version +// chainID, +// address(this) +// )); +// } + + function __ERC20Permit_initialize(string memory name_, string memory symbol_, uint8 decimals_) internal initializer { + __ERC20Permit_init_unchain(); + __ERC20_initialize(name_, symbol_, decimals_); + } + + function __ERC20Permit_init_unchain() internal initializer { uint256 chainID; assembly { chainID := chainid() } DOMAIN_SEPARATOR = keccak256(abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), - keccak256(bytes(name())), - keccak256(bytes("1")), // Version - chainID, - address(this) - )); + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), + keccak256(bytes(name())), + keccak256(bytes("1")), // Version + chainID, + address(this) + )); } /** @@ -947,7 +1033,7 @@ interface IOwnable { function pullManagement() external; } -contract Ownable is IOwnable { +contract Ownable is IOwnable, Initializable { address internal _owner; address internal _newOwner; @@ -955,7 +1041,16 @@ contract Ownable is IOwnable { event OwnershipPushed(address indexed previousOwner, address indexed newOwner); event OwnershipPulled(address indexed previousOwner, address indexed newOwner); - constructor () { +// constructor () { +// _owner = msg.sender; +// emit OwnershipPushed( address(0), _owner ); +// } + + function __Ownable_initialize() internal initializer { + __Ownable_init_unchain(); + } + + function __Ownable_init_unchain() internal initializer { _owner = msg.sender; emit OwnershipPushed( address(0), _owner ); } @@ -997,7 +1092,7 @@ contract sSynassets is ERC20Permit, Ownable { } address public stakingContract; - address public initializer; + address public initializer_; event LogSupply(uint256 indexed epoch, uint256 timestamp, uint256 totalSupply ); event LogRebase( uint256 indexed epoch, uint256 rebase, uint256 index ); @@ -1031,14 +1126,26 @@ contract sSynassets is ERC20Permit, Ownable { mapping ( address => mapping ( address => uint256 ) ) private _allowedValue; - constructor() ERC20("Staked Synassets Token", "sSYNASSETS", 9) ERC20Permit() { - initializer = msg.sender; +// constructor() ERC20("Staked Synassets Token", "sSYNASSETS", 9) ERC20Permit() { +// initializer_ = msg.sender; +// _totalSupply = INITIAL_FRAGMENTS_SUPPLY; +// _gonsPerFragment = TOTAL_GONS.div(_totalSupply); +// } + + function __sSynassets_initialize() external initializer { + __SATTimelock_init_unchain(); + __Ownable_initialize(); + __ERC20Permit_initialize("Staked Synassets Token", "sSYNASSETS", 9); + } + + function __SATTimelock_init_unchain() internal initializer { + initializer_ = msg.sender; _totalSupply = INITIAL_FRAGMENTS_SUPPLY; _gonsPerFragment = TOTAL_GONS.div(_totalSupply); } function initialize( address stakingContract_ ) external returns ( bool ) { - require( msg.sender == initializer ); + require( msg.sender == initializer_ ); require( stakingContract_ != address(0) ); stakingContract = stakingContract_; _gonBalances[ stakingContract ] = TOTAL_GONS; @@ -1046,7 +1153,7 @@ contract sSynassets is ERC20Permit, Ownable { emit Transfer( address(0x0), stakingContract, _totalSupply ); emit LogStakingContractUpdated( stakingContract_ ); - initializer = address(0); + initializer_ = address(0); return true; }