From 3b32beeaab3ff48b8ec9dc70f416d7ac96f4bdfb Mon Sep 17 00:00:00 2001 From: bajpai244 Date: Tue, 14 Dec 2021 20:47:42 +0530 Subject: [PATCH] replace `Treasury.sol` contract with the contract deployed on the Avalanche C-Chain! Afer going through the `Treasury.sol` contract in this repository I realized that it is not the same as deployed on the Avalanche C-Chain! Link to contract deployed on the C-Chain => [https://snowtrace.io/address/0x1c46450211cb2646cc1da3c5242422967ed9e04c#code](https://snowtrace.io/address/0x1c46450211cb2646cc1da3c5242422967ed9e04c#code) This, PR will resolve this issue and will let the Treasury.sol hold the right contract that is deployed on the C-Chain! --- Treasury.sol | 295 ++++++++++++++++++++++----------------------------- 1 file changed, 128 insertions(+), 167 deletions(-) diff --git a/Treasury.sol b/Treasury.sol index b336043..820d824 100644 --- a/Treasury.sol +++ b/Treasury.sol @@ -1,62 +1,67 @@ +/** + *Submitted for verification at snowtrace.io on 2021-11-06 +*/ + // SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity 0.7.5; -library LowGasSafeMath { - /// @notice Returns x + y, reverts if sum overflows uint256 - /// @param x The augend - /// @param y The addend - /// @return z The sum of x and y - function add(uint256 x, uint256 y) internal pure returns (uint256 z) { - require((z = x + y) >= x); - } +library SafeMath { + + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); - function add32(uint32 x, uint32 y) internal pure returns (uint32 z) { - require((z = x + y) >= x); + return c; } - /// @notice Returns x - y, reverts if underflows - /// @param x The minuend - /// @param y The subtrahend - /// @return z The difference of x and y - function sub(uint256 x, uint256 y) internal pure returns (uint256 z) { - require((z = x - y) <= x); + function add32(uint32 a, uint32 b) internal pure returns (uint32) { + uint32 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; } - function sub32(uint32 x, uint32 y) internal pure returns (uint32 z) { - require((z = x - y) <= x); + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction overflow"); } - /// @notice Returns x * y, reverts if overflows - /// @param x The multiplicand - /// @param y The multiplier - /// @return z The product of x and y - function mul(uint256 x, uint256 y) internal pure returns (uint256 z) { - require(x == 0 || (z = x * y) / x == y); + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; } - function mul32(uint32 x, uint32 y) internal pure returns (uint32 z) { - require(x == 0 || (z = x * y) / x == y); + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; } - /// @notice Returns x + y, reverts if overflows or underflows - /// @param x The augend - /// @param y The addend - /// @return z The sum of x and y - function add(int256 x, int256 y) internal pure returns (int256 z) { - require((z = x + y) >= x == (y >= 0)); + function mul32(uint32 a, uint32 b) internal pure returns (uint32) { + if (a == 0) { + return 0; + } + + uint32 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; } - /// @notice Returns x - y, reverts if overflows or underflows - /// @param x The minuend - /// @param y The subtrahend - /// @return z The difference of x and y - function sub(int256 x, int256 y) internal pure returns (int256 z) { - require((z = x - y) <= x == (y >= 0)); + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); } - function div(uint256 x, uint256 y) internal pure returns(uint256 z){ - require(y > 0); - z=x/y; + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b > 0, errorMessage); + uint256 c = a / b; + return c; } } @@ -127,62 +132,54 @@ library Address { } } -contract OwnableData { - address public owner; - address public pendingOwner; +interface IOwnable { + function manager() external view returns (address); + + function renounceManagement() external; + + function pushManagement( address newOwner_ ) external; + + function pullManagement() external; } -contract Ownable is OwnableData { - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /// @notice `owner` defaults to msg.sender on construction. - constructor() { - owner = msg.sender; - emit OwnershipTransferred(address(0), msg.sender); - } - - /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner. - /// Can only be invoked by the current `owner`. - /// @param newOwner Address of the new owner. - /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`. - /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise. - function transferOwnership( - address newOwner, - bool direct, - bool renounce - ) public onlyOwner { - if (direct) { - // Checks - require(newOwner != address(0) || renounce, "Ownable: zero address"); - - // Effects - emit OwnershipTransferred(owner, newOwner); - owner = newOwner; - pendingOwner = address(0); - } else { - // Effects - pendingOwner = newOwner; - } - } +contract Ownable is IOwnable { + + address internal _owner; + address internal _newOwner; - /// @notice Needs to be called by `pendingOwner` to claim ownership. - function claimOwnership() public { - address _pendingOwner = pendingOwner; + event OwnershipPushed(address indexed previousOwner, address indexed newOwner); + event OwnershipPulled(address indexed previousOwner, address indexed newOwner); - // Checks - require(msg.sender == _pendingOwner, "Ownable: caller != pending owner"); + constructor () { + _owner = msg.sender; + emit OwnershipPushed( address(0), _owner ); + } - // Effects - emit OwnershipTransferred(owner, _pendingOwner); - owner = _pendingOwner; - pendingOwner = address(0); + function manager() public view override returns (address) { + return _owner; } - /// @notice Only allows the `owner` to execute the function. - modifier onlyOwner() { - require(msg.sender == owner, "Ownable: caller is not the owner"); + modifier onlyManager() { + require( _owner == msg.sender, "Ownable: caller is not the owner" ); _; } + + function renounceManagement() public virtual override onlyManager() { + emit OwnershipPushed( _owner, address(0) ); + _owner = address(0); + } + + function pushManagement( address newOwner_ ) public virtual override onlyManager() { + require( newOwner_ != address(0), "Ownable: new owner is the zero address"); + emit OwnershipPushed( _owner, newOwner_ ); + _newOwner = newOwner_; + } + + function pullManagement() public virtual override { + require( msg.sender == _newOwner, "Ownable: must be new owner to pull"); + emit OwnershipPulled( _owner, _newOwner ); + _owner = _newOwner; + } } interface IERC20 { @@ -204,7 +201,7 @@ interface IERC20 { } library SafeERC20 { - using LowGasSafeMath for uint256; + using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { @@ -230,7 +227,7 @@ interface IERC20Mintable { function mint( address account_, uint256 ammount_ ) external; } -interface ITIMEERC20 is IERC20Mintable, IERC20 { +interface IOHMERC20 { function burnFrom(address account_, uint256 amount_) external; } @@ -240,8 +237,8 @@ interface IBondCalculator { contract TimeTreasury is Ownable { - using LowGasSafeMath for uint; - using LowGasSafeMath for uint32; + using SafeMath for uint; + using SafeMath for uint32; using SafeERC20 for IERC20; event Deposit( address indexed token, uint amount, uint value ); @@ -254,7 +251,6 @@ contract TimeTreasury is Ownable { event RewardsMinted( address indexed caller, address indexed recipient, uint amount ); event ChangeQueued( MANAGING indexed managing, address queued ); event ChangeActivated( MANAGING indexed managing, address activated, bool result ); - event ChangeLimitAmount( uint256 amount ); enum MANAGING { RESERVEDEPOSITOR, @@ -269,7 +265,7 @@ contract TimeTreasury is Ownable { SOHM } - ITIMEERC20 public immutable Time; + address public immutable Time; uint32 public immutable secondsNeededForQueue; address[] public reserveTokens; // Push only, beware false-positives. @@ -311,12 +307,7 @@ contract TimeTreasury is Ownable { mapping( address => bool ) public isRewardManager; mapping( address => uint32 ) public rewardManagerQueue; // Delays changes to mapping. - mapping( address => uint256 ) public hourlyLimitAmounts; // tracks amounts - mapping( address => uint32 ) public hourlyLimitQueue; // Delays changes to mapping. - - uint256 public limitAmount; - - IERC20 public MEMOries; + address public MEMOries; uint public sOHMQueue; // Delays change to sOHM address uint public totalReserves; // Risk-free value of all assets @@ -325,11 +316,10 @@ contract TimeTreasury is Ownable { constructor ( address _Time, address _MIM, - uint32 _secondsNeededForQueue, - uint256 _limitAmount + uint32 _secondsNeededForQueue ) { require( _Time != address(0) ); - Time = ITIMEERC20(_Time); + Time = _Time; isReserveToken[ _MIM ] = true; reserveTokens.push( _MIM ); @@ -338,16 +328,10 @@ contract TimeTreasury is Ownable { // liquidityTokens.push( _OHMDAI ); secondsNeededForQueue = _secondsNeededForQueue; - limitAmount = _limitAmount; - } - - function setLimitAmount(uint amount) external onlyOwner { - limitAmount = amount; - emit ChangeLimitAmount(limitAmount); } /** - @notice allow approved address to deposit an asset for Time + @notice allow approved address to deposit an asset for OHM @param _amount uint @param _token address @param _profit uint @@ -364,10 +348,9 @@ contract TimeTreasury is Ownable { } uint value = valueOf(_token, _amount); - // mint Time needed and store amount of rewards for distribution + // mint OHM needed and store amount of rewards for distribution send_ = value.sub( _profit ); - limitRequirements(msg.sender, send_); - Time.mint( msg.sender, send_ ); + IERC20Mintable( Time ).mint( msg.sender, send_ ); totalReserves = totalReserves.add( value ); emit ReservesUpdated( totalReserves ); @@ -376,16 +359,16 @@ contract TimeTreasury is Ownable { } /** - @notice allow approved address to burn Time for reserves + @notice allow approved address to burn OHM for reserves @param _amount uint @param _token address */ function withdraw( uint _amount, address _token ) external { require( isReserveToken[ _token ], "Not accepted" ); // Only reserves can be used for redemptions - require( isReserveSpender[ msg.sender ], "Not approved" ); + require( isReserveSpender[ msg.sender ] == true, "Not approved" ); uint value = valueOf( _token, _amount ); - Time.burnFrom( msg.sender, value ); + IOHMERC20( Time ).burnFrom( msg.sender, value ); totalReserves = totalReserves.sub( value ); emit ReservesUpdated( totalReserves ); @@ -406,18 +389,17 @@ contract TimeTreasury is Ownable { uint value = valueOf( _token, _amount ); - uint maximumDebt = MEMOries.balanceOf( msg.sender ); // Can only borrow against sOHM held - uint balance = debtorBalance[ msg.sender ]; - uint availableDebt = maximumDebt.sub( balance ); + uint maximumDebt = IERC20( MEMOries ).balanceOf( msg.sender ); // Can only borrow against sOHM held + uint availableDebt = maximumDebt.sub( debtorBalance[ msg.sender ] ); require( value <= availableDebt, "Exceeds debt limit" ); - limitRequirements(msg.sender, value); - debtorBalance[ msg.sender ] = balance.add( value ); + + debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].add( value ); totalDebt = totalDebt.add( value ); totalReserves = totalReserves.sub( value ); emit ReservesUpdated( totalReserves ); - - IERC20( _token ).safeTransfer( msg.sender, _amount ); + + IERC20( _token ).transfer( msg.sender, _amount ); emit CreateDebt( msg.sender, _token, _amount, value ); } @@ -444,19 +426,18 @@ contract TimeTreasury is Ownable { } /** - @notice allow approved address to repay borrowed reserves with Time + @notice allow approved address to repay borrowed reserves with OHM @param _amount uint */ - function repayDebtWithTime( uint _amount ) external { - require( isDebtor[ msg.sender ], "Not approved as debtor" ); - require( isReserveSpender[ msg.sender ], "Not approved as spender" ); + function repayDebtWithOHM( uint _amount ) external { + require( isDebtor[ msg.sender ], "Not approved" ); - Time.burnFrom( msg.sender, _amount ); + IOHMERC20( Time ).burnFrom( msg.sender, _amount ); debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( _amount ); totalDebt = totalDebt.sub( _amount ); - emit RepayDebt( msg.sender, address(Time), _amount, _amount ); + emit RepayDebt( msg.sender, Time, _amount, _amount ); } /** @@ -465,16 +446,15 @@ contract TimeTreasury is Ownable { @param _amount uint */ function manage( address _token, uint _amount ) external { - uint value = valueOf(_token, _amount); if( isLiquidityToken[ _token ] ) { require( isLiquidityManager[ msg.sender ], "Not approved" ); - require(value <= excessReserves()); } else { - if (isReserveToken[ _token ]) require(value <= excessReserves()); require( isReserveManager[ msg.sender ], "Not approved" ); } - - limitRequirements(msg.sender, value); + + uint value = valueOf(_token, _amount); + require( value <= excessReserves(), "Insufficient reserves" ); + totalReserves = totalReserves.sub( value ); emit ReservesUpdated( totalReserves ); @@ -489,8 +469,8 @@ contract TimeTreasury is Ownable { function mintRewards( address _recipient, uint _amount ) external { require( isRewardManager[ msg.sender ], "Not approved" ); require( _amount <= excessReserves(), "Insufficient reserves" ); - limitRequirements(msg.sender, _amount); - Time.mint( _recipient, _amount ); + + IERC20Mintable( Time ).mint( _recipient, _amount ); emit RewardsMinted( msg.sender, _recipient, _amount ); } @@ -500,14 +480,14 @@ contract TimeTreasury is Ownable { @return uint */ function excessReserves() public view returns ( uint ) { - return totalReserves.sub( Time.totalSupply().sub( totalDebt ) ); + return totalReserves.sub( IERC20( Time ).totalSupply().sub( totalDebt ) ); } /** @notice takes inventory of all tracked assets @notice always consolidate to recognized reserves before audit */ - function auditReserves() external onlyOwner { + function auditReserves() external onlyManager() { uint reserves; for( uint i = 0; i < reserveTokens.length; i++ ) { reserves = reserves.add ( @@ -525,15 +505,15 @@ contract TimeTreasury is Ownable { } /** - @notice returns Time valuation of asset + @notice returns OHM valuation of asset @param _token address @param _amount uint @return value_ uint */ function valueOf( address _token, uint _amount ) public view returns ( uint value_ ) { if ( isReserveToken[ _token ] ) { - // convert amount to match Time decimals - value_ = _amount.mul( 10 ** Time.decimals() ).div( 10 ** IERC20( _token ).decimals() ); + // convert amount to match OHM decimals + value_ = _amount.mul( 10 ** IERC20( Time ).decimals() ).div( 10 ** IERC20( _token ).decimals() ); } else if ( isLiquidityToken[ _token ] ) { value_ = IBondCalculator( bondCalculator[ _token ] ).valuation( _token, _amount ); } @@ -545,8 +525,8 @@ contract TimeTreasury is Ownable { @param _address address @return bool */ - function queue( MANAGING _managing, address _address ) external onlyOwner returns ( bool ) { - require( _address != address(0), "IA" ); + function queue( MANAGING _managing, address _address ) external onlyManager() returns ( bool ) { + require( _address != address(0) ); if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0 reserveDepositorQueue[ _address ] = uint32(block.timestamp).add32( secondsNeededForQueue ); } else if ( _managing == MANAGING.RESERVESPENDER ) { // 1 @@ -584,8 +564,8 @@ contract TimeTreasury is Ownable { MANAGING _managing, address _address, address _calculator - ) external onlyOwner returns ( bool ) { - require( _address != address(0), "IA" ); + ) external onlyManager() returns ( bool ) { + require( _address != address(0) ); bool result; if ( _managing == MANAGING.RESERVEDEPOSITOR ) { // 0 if ( requirements( reserveDepositorQueue, isReserveDepositor, _address ) ) { @@ -610,12 +590,11 @@ contract TimeTreasury is Ownable { } else if ( _managing == MANAGING.RESERVETOKEN ) { // 2 if ( requirements( reserveTokenQueue, isReserveToken, _address ) ) { reserveTokenQueue[ _address ] = 0; - if( !listContains( reserveTokens, _address ) && !listContains( liquidityTokens, _address ) ) { + if( !listContains( reserveTokens, _address ) ) { reserveTokens.push( _address ); } } result = !isReserveToken[ _address ]; - require(!result || !isLiquidityToken[_address], "Do not add to both types of token"); isReserveToken[ _address ] = result; } else if ( _managing == MANAGING.RESERVEMANAGER ) { // 3 @@ -643,12 +622,11 @@ contract TimeTreasury is Ownable { } else if ( _managing == MANAGING.LIQUIDITYTOKEN ) { // 5 if ( requirements( LiquidityTokenQueue, isLiquidityToken, _address ) ) { LiquidityTokenQueue[ _address ] = 0; - if( !listContains( liquidityTokens, _address ) && !listContains( reserveTokens, _address ) ) { + if( !listContains( liquidityTokens, _address ) ) { liquidityTokens.push( _address ); } } result = !isLiquidityToken[ _address ]; - require(!result || !isReserveToken[_address], "Do not add to both types of token"); isLiquidityToken[ _address ] = result; bondCalculator[ _address ] = _calculator; @@ -684,7 +662,7 @@ contract TimeTreasury is Ownable { } else if ( _managing == MANAGING.SOHM ) { // 9 sOHMQueue = 0; - MEMOries = IERC20(_address); + MEMOries = _address; result = true; } else return false; @@ -712,23 +690,6 @@ contract TimeTreasury is Ownable { } return false; } - /** - @notice checks LimitRequirements - @param _address address - @param _address value - */ - function limitRequirements( - address _address, - uint256 value - ) internal { - if (block.timestamp.sub(hourlyLimitQueue[_address]) >= 1 hours) - { - hourlyLimitAmounts[_address] = limitAmount; - hourlyLimitQueue[_address] = uint32(block.timestamp); - } - hourlyLimitAmounts[_address] = hourlyLimitAmounts[_address].sub(value); - } - /** @notice checks array to ensure against duplicate @param _list address[]