文件 1 的 7:Address.sol
pragma solidity 0.7.5;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
function addressToString(address _address) internal pure returns(string memory) {
bytes32 _bytes = bytes32(uint256(_address));
bytes memory HEX = "0123456789abcdef";
bytes memory _addr = new bytes(42);
_addr[0] = '0';
_addr[1] = 'x';
for(uint256 i = 0; i < 20; i++) {
_addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];
_addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
}
return string(_addr);
}
}
文件 2 的 7:AxeTreasury.sol
pragma solidity 0.7.5;
import "./libraries/Ownable.sol";
import "./libraries/SafeMath.sol";
import "./libraries/ERC20.sol";
interface IAxeERC20 {
function burnFrom(address account_, uint256 amount_) external;
}
interface IBondCalculator {
function valuation( address pair_, uint amount_ ) external view returns ( uint _value );
}
contract AxeTreasury is Ownable {
using SafeMath for uint;
using SafeERC20 for IERC20;
event Deposit( address indexed token, uint amount, uint value );
event Withdrawal( address indexed token, uint amount, uint value );
event CreateDebt( address indexed debtor, address indexed token, uint amount, uint value );
event RepayDebt( address indexed debtor, address indexed token, uint amount, uint value );
event ReservesManaged( address indexed token, uint amount );
event ReservesUpdated( uint indexed totalReserves );
event ReservesAudited( uint indexed totalReserves );
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 );
enum MANAGING { RESERVEDEPOSITOR, RESERVESPENDER, RESERVETOKEN, RESERVEMANAGER, LIQUIDITYDEPOSITOR, LIQUIDITYTOKEN, LIQUIDITYMANAGER, DEBTOR, REWARDMANAGER, SAXE }
address public immutable AXE;
uint public immutable blocksNeededForQueue;
address[] public reserveTokens;
mapping( address => bool ) public isReserveToken;
mapping( address => uint ) public reserveTokenQueue;
address[] public reserveDepositors;
mapping( address => bool ) public isReserveDepositor;
mapping( address => uint ) public reserveDepositorQueue;
address[] public reserveSpenders;
mapping( address => bool ) public isReserveSpender;
mapping( address => uint ) public reserveSpenderQueue;
address[] public liquidityTokens;
mapping( address => bool ) public isLiquidityToken;
mapping( address => uint ) public LiquidityTokenQueue;
address[] public liquidityDepositors;
mapping( address => bool ) public isLiquidityDepositor;
mapping( address => uint ) public LiquidityDepositorQueue;
mapping( address => address ) public bondCalculator;
address[] public reserveManagers;
mapping( address => bool ) public isReserveManager;
mapping( address => uint ) public ReserveManagerQueue;
address[] public liquidityManagers;
mapping( address => bool ) public isLiquidityManager;
mapping( address => uint ) public LiquidityManagerQueue;
address[] public debtors;
mapping( address => bool ) public isDebtor;
mapping( address => uint ) public debtorQueue;
mapping( address => uint ) public debtorBalance;
address[] public rewardManagers;
mapping( address => bool ) public isRewardManager;
mapping( address => uint ) public rewardManagerQueue;
address public sAXE;
uint public sAXEQueue;
uint public totalReserves;
uint public totalDebt;
constructor (
address _AXE,
address _DAI,
address _AXEDAI,
address _bondCalculator,
uint _blocksNeededForQueue
) {
require( _AXE != address(0) );
AXE = _AXE;
isReserveToken[ _DAI ] = true;
reserveTokens.push( _DAI );
isLiquidityToken[ _AXEDAI ] = true;
liquidityTokens.push( _AXEDAI );
bondCalculator[_AXEDAI] = _bondCalculator;
blocksNeededForQueue = _blocksNeededForQueue;
}
function deposit( uint _amount, address _token, uint _profit ) external returns ( uint send_ ) {
require( isReserveToken[ _token ] || isLiquidityToken[ _token ], "Not accepted" );
IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );
if ( isReserveToken[ _token ] ) {
require( isReserveDepositor[ msg.sender ], "Not approved" );
} else {
require( isLiquidityDepositor[ msg.sender ], "Not approved" );
}
uint value = valueOfToken(_token, _amount);
send_ = value.sub( _profit );
IERC20Mintable( AXE ).mint( msg.sender, send_ );
totalReserves = totalReserves.add( value );
emit ReservesUpdated( totalReserves );
emit Deposit( _token, _amount, value );
}
function withdraw( uint _amount, address _token ) external {
require( isReserveToken[ _token ], "Not accepted" );
require( isReserveSpender[ msg.sender ] == true, "Not approved" );
uint value = valueOfToken( _token, _amount );
IAxeERC20( AXE ).burnFrom( msg.sender, value );
totalReserves = totalReserves.sub( value );
emit ReservesUpdated( totalReserves );
IERC20( _token ).safeTransfer( msg.sender, _amount );
emit Withdrawal( _token, _amount, value );
}
function incurDebt( uint _amount, address _token ) external {
require( isDebtor[ msg.sender ], "Not approved" );
require( isReserveToken[ _token ], "Not accepted" );
uint value = valueOfToken( _token, _amount );
uint maximumDebt = IERC20( sAXE ).balanceOf( msg.sender );
uint availableDebt = maximumDebt.sub( debtorBalance[ msg.sender ] );
require( value <= availableDebt, "Exceeds debt limit" );
debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].add( value );
totalDebt = totalDebt.add( value );
totalReserves = totalReserves.sub( value );
emit ReservesUpdated( totalReserves );
IERC20( _token ).transfer( msg.sender, _amount );
emit CreateDebt( msg.sender, _token, _amount, value );
}
function repayDebtWithReserve( uint _amount, address _token ) external {
require( isDebtor[ msg.sender ], "Not approved" );
require( isReserveToken[ _token ], "Not accepted" );
IERC20( _token ).safeTransferFrom( msg.sender, address(this), _amount );
uint value = valueOfToken( _token, _amount );
debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( value );
totalDebt = totalDebt.sub( value );
totalReserves = totalReserves.add( value );
emit ReservesUpdated( totalReserves );
emit RepayDebt( msg.sender, _token, _amount, value );
}
function repayDebtWithAXE( uint _amount ) external {
require( isDebtor[ msg.sender ], "Not approved" );
IAxeERC20( AXE ).burnFrom( msg.sender, _amount );
debtorBalance[ msg.sender ] = debtorBalance[ msg.sender ].sub( _amount );
totalDebt = totalDebt.sub( _amount );
emit RepayDebt( msg.sender, AXE, _amount, _amount );
}
function manage( address _token, uint _amount ) external {
if( isLiquidityToken[ _token ] ) {
require( isLiquidityManager[ msg.sender ], "Not approved" );
} else {
require( isReserveManager[ msg.sender ], "Not approved" );
}
uint value = valueOfToken(_token, _amount);
require( value <= excessReserves(), "Insufficient reserves" );
totalReserves = totalReserves.sub( value );
emit ReservesUpdated( totalReserves );
IERC20( _token ).safeTransfer( msg.sender, _amount );
emit ReservesManaged( _token, _amount );
}
function mintRewards( address _recipient, uint _amount ) external {
require( isRewardManager[ msg.sender ], "Not approved" );
require( _amount <= excessReserves(), "Insufficient reserves" );
IERC20Mintable( AXE ).mint( _recipient, _amount );
emit RewardsMinted( msg.sender, _recipient, _amount );
}
function excessReserves() public view returns ( uint ) {
return totalReserves.sub( IERC20( AXE ).totalSupply().sub( totalDebt ) );
}
function auditReserves() external onlyOwner() {
uint reserves;
for( uint i = 0; i < reserveTokens.length; i++ ) {
reserves = reserves.add (
valueOfToken( reserveTokens[ i ], IERC20( reserveTokens[ i ] ).balanceOf( address(this) ) )
);
}
for( uint i = 0; i < liquidityTokens.length; i++ ) {
reserves = reserves.add (
valueOfToken( liquidityTokens[ i ], IERC20( liquidityTokens[ i ] ).balanceOf( address(this) ) )
);
}
totalReserves = reserves;
emit ReservesUpdated( reserves );
emit ReservesAudited( reserves );
}
function valueOfToken( address _token, uint _amount ) public view returns ( uint value_ ) {
if ( isReserveToken[ _token ] ) {
value_ = _amount.mul( 10 ** IERC20( AXE ).decimals() ).div( 10 ** IERC20( _token ).decimals() );
} else if ( isLiquidityToken[ _token ] ) {
value_ = IBondCalculator( bondCalculator[ _token ] ).valuation( _token, _amount );
}
}
function queue( MANAGING _managing, address _address ) external onlyOwner() returns ( bool ) {
require( _address != address(0) );
if ( _managing == MANAGING.RESERVEDEPOSITOR ) {
reserveDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.RESERVESPENDER ) {
reserveSpenderQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.RESERVETOKEN ) {
reserveTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.RESERVEMANAGER ) {
ReserveManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );
} else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) {
LiquidityDepositorQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.LIQUIDITYTOKEN ) {
LiquidityTokenQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.LIQUIDITYMANAGER ) {
LiquidityManagerQueue[ _address ] = block.number.add( blocksNeededForQueue.mul( 2 ) );
} else if ( _managing == MANAGING.DEBTOR ) {
debtorQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.REWARDMANAGER ) {
rewardManagerQueue[ _address ] = block.number.add( blocksNeededForQueue );
} else if ( _managing == MANAGING.SAXE ) {
sAXEQueue = block.number.add( blocksNeededForQueue );
} else return false;
emit ChangeQueued( _managing, _address );
return true;
}
function toggle( MANAGING _managing, address _address, address _calculator ) external onlyOwner() returns ( bool ) {
require( _address != address(0) );
bool result;
if ( _managing == MANAGING.RESERVEDEPOSITOR ) {
if ( requirements( reserveDepositorQueue, isReserveDepositor, _address ) ) {
reserveDepositorQueue[ _address ] = 0;
if( !listContains( reserveDepositors, _address ) ) {
reserveDepositors.push( _address );
}
}
result = !isReserveDepositor[ _address ];
isReserveDepositor[ _address ] = result;
} else if ( _managing == MANAGING.RESERVESPENDER ) {
if ( requirements( reserveSpenderQueue, isReserveSpender, _address ) ) {
reserveSpenderQueue[ _address ] = 0;
if( !listContains( reserveSpenders, _address ) ) {
reserveSpenders.push( _address );
}
}
result = !isReserveSpender[ _address ];
isReserveSpender[ _address ] = result;
} else if ( _managing == MANAGING.RESERVETOKEN ) {
if ( requirements( reserveTokenQueue, isReserveToken, _address ) ) {
reserveTokenQueue[ _address ] = 0;
if( !listContains( reserveTokens, _address ) ) {
reserveTokens.push( _address );
}
}
result = !isReserveToken[ _address ];
isReserveToken[ _address ] = result;
} else if ( _managing == MANAGING.RESERVEMANAGER ) {
if ( requirements( ReserveManagerQueue, isReserveManager, _address ) ) {
reserveManagers.push( _address );
ReserveManagerQueue[ _address ] = 0;
if( !listContains( reserveManagers, _address ) ) {
reserveManagers.push( _address );
}
}
result = !isReserveManager[ _address ];
isReserveManager[ _address ] = result;
} else if ( _managing == MANAGING.LIQUIDITYDEPOSITOR ) {
if ( requirements( LiquidityDepositorQueue, isLiquidityDepositor, _address ) ) {
liquidityDepositors.push( _address );
LiquidityDepositorQueue[ _address ] = 0;
if( !listContains( liquidityDepositors, _address ) ) {
liquidityDepositors.push( _address );
}
}
result = !isLiquidityDepositor[ _address ];
isLiquidityDepositor[ _address ] = result;
} else if ( _managing == MANAGING.LIQUIDITYTOKEN ) {
if ( requirements( LiquidityTokenQueue, isLiquidityToken, _address ) ) {
LiquidityTokenQueue[ _address ] = 0;
if( !listContains( liquidityTokens, _address ) ) {
liquidityTokens.push( _address );
}
}
result = !isLiquidityToken[ _address ];
isLiquidityToken[ _address ] = result;
bondCalculator[ _address ] = _calculator;
} else if ( _managing == MANAGING.LIQUIDITYMANAGER ) {
if ( requirements( LiquidityManagerQueue, isLiquidityManager, _address ) ) {
LiquidityManagerQueue[ _address ] = 0;
if( !listContains( liquidityManagers, _address ) ) {
liquidityManagers.push( _address );
}
}
result = !isLiquidityManager[ _address ];
isLiquidityManager[ _address ] = result;
} else if ( _managing == MANAGING.DEBTOR ) {
if ( requirements( debtorQueue, isDebtor, _address ) ) {
debtorQueue[ _address ] = 0;
if( !listContains( debtors, _address ) ) {
debtors.push( _address );
}
}
result = !isDebtor[ _address ];
isDebtor[ _address ] = result;
} else if ( _managing == MANAGING.REWARDMANAGER ) {
if ( requirements( rewardManagerQueue, isRewardManager, _address ) ) {
rewardManagerQueue[ _address ] = 0;
if( !listContains( rewardManagers, _address ) ) {
rewardManagers.push( _address );
}
}
result = !isRewardManager[ _address ];
isRewardManager[ _address ] = result;
} else if ( _managing == MANAGING.SAXE ) {
sAXEQueue = 0;
sAXE = _address;
result = true;
} else return false;
emit ChangeActivated( _managing, _address, result );
return true;
}
function requirements(
mapping( address => uint ) storage queue_,
mapping( address => bool ) storage status_,
address _address
) internal view returns ( bool ) {
if ( !status_[ _address ] ) {
require( queue_[ _address ] != 0, "Must queue" );
require( queue_[ _address ] <= block.number, "Queue not expired" );
return true;
} return false;
}
function listContains( address[] storage _list, address _token ) internal view returns ( bool ) {
for( uint i = 0; i < _list.length; i++ ) {
if( _list[ i ] == _token ) {
return true;
}
}
return false;
}
}
文件 3 的 7:Counters.sol
pragma solidity 0.7.5;
import "./SafeMath.sol";
library Counters {
using SafeMath for uint256;
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
counter._value += 1;
}
function decrement(Counter storage counter) internal {
counter._value = counter._value.sub(1);
}
}
文件 4 的 7:ERC20.sol
pragma solidity 0.7.5;
import "../interfaces/IERC20.sol";
import "./SafeMath.sol";
import "./Counters.sol";
import "./Address.sol";
abstract contract ERC20 is IERC20 {
using SafeMath for uint256;
bytes32 constant private ERC20TOKEN_ERC1820_INTERFACE_ID = keccak256( "ERC20Token" );
mapping (address => uint256) internal _balances;
mapping (address => mapping (address => uint256)) internal _allowances;
uint256 internal _totalSupply;
string internal _name;
string internal _symbol;
uint8 internal _decimals;
constructor (string memory name_, string memory symbol_, uint8 decimals_) {
_name = name_;
_symbol = symbol_;
_decimals = decimals_;
}
function name() public view override returns (string memory) {
return _name;
}
function symbol() public view override returns (string memory) {
return _symbol;
}
function decimals() public view override returns (uint8) {
return _decimals;
}
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account_, uint256 ammount_) internal virtual {
require(account_ != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address( this ), account_, ammount_);
_totalSupply = _totalSupply.add(ammount_);
_balances[account_] = _balances[account_].add(ammount_);
emit Transfer(address( this ), account_, ammount_);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _beforeTokenTransfer( address from_, address to_, uint256 amount_ ) internal virtual { }
}
interface IERC2612Permit {
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
}
abstract contract ERC20Permit is ERC20, IERC2612Permit {
using Counters for Counters.Counter;
mapping(address => Counters.Counter) private _nonces;
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
bytes32 public DOMAIN_SEPARATOR;
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")),
chainID,
address(this)
)
);
}
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual override {
require(block.timestamp <= deadline, "Permit: expired deadline");
bytes32 hashStruct =
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, amount, _nonces[owner].current(), deadline));
bytes32 _hash = keccak256(abi.encodePacked(uint16(0x1901), DOMAIN_SEPARATOR, hashStruct));
address signer = ecrecover(_hash, v, r, s);
require(signer != address(0) && signer == owner, "ZeroSwapPermit: Invalid signature");
_nonces[owner].increment();
_approve(owner, spender, amount);
}
function nonces(address owner) public view override returns (uint256) {
return _nonces[owner].current();
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 5 的 7:IERC20.sol
pragma solidity >=0.5.0;
interface IERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}
interface IERC20Mintable {
function mint( uint256 amount_ ) external;
function mint( address account_, uint256 ammount_ ) external;
}
文件 6 的 7:Ownable.sol
pragma solidity 0.7.5;
interface IOwnable {
function owner() external view returns (address);
function renounceManagement() external;
function pushManagement( address newOwner_ ) external;
function pullManagement() external;
}
contract Ownable is IOwnable {
address internal _owner;
address internal _newOwner;
event OwnershipPushed(address indexed previousOwner, address indexed newOwner);
event OwnershipPulled(address indexed previousOwner, address indexed newOwner);
constructor () {
_owner = msg.sender;
emit OwnershipPushed( 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 renounceManagement() public virtual override onlyOwner() {
emit OwnershipPushed( _owner, address(0) );
_owner = address(0);
}
function pushManagement( address newOwner_ ) public virtual override onlyOwner() {
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;
}
}
文件 7 的 7:SafeMath.sol
pragma solidity 0.7.5;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
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;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function sqrrt(uint256 a) internal pure returns (uint c) {
if (a > 3) {
c = a;
uint b = add( div( a, 2), 1 );
while (b < c) {
c = b;
b = div( add( div( a, b ), b), 2 );
}
} else if (a != 0) {
c = 1;
}
}
}
{
"compilationTarget": {
"contracts/AxeTreasury.sol": "AxeTreasury"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_AXE","type":"address"},{"internalType":"address","name":"_DAI","type":"address"},{"internalType":"address","name":"_AXEDAI","type":"address"},{"internalType":"address","name":"_bondCalculator","type":"address"},{"internalType":"uint256","name":"_blocksNeededForQueue","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum AxeTreasury.MANAGING","name":"managing","type":"uint8"},{"indexed":false,"internalType":"address","name":"activated","type":"address"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"ChangeActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum AxeTreasury.MANAGING","name":"managing","type":"uint8"},{"indexed":false,"internalType":"address","name":"queued","type":"address"}],"name":"ChangeQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"debtor","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"CreateDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"debtor","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"RepayDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"totalReserves","type":"uint256"}],"name":"ReservesAudited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReservesManaged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"totalReserves","type":"uint256"}],"name":"ReservesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardsMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"AXE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"LiquidityDepositorQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"LiquidityManagerQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"LiquidityTokenQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ReserveManagerQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auditReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksNeededForQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bondCalculator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"debtorBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"debtorQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"debtors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_profit","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"send_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"excessReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"incurDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isDebtor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLiquidityDepositor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLiquidityManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLiquidityToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReserveDepositor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReserveManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReserveSpender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isReserveToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRewardManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liquidityDepositors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liquidityManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liquidityTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"manage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner_","type":"address"}],"name":"pushManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum AxeTreasury.MANAGING","name":"_managing","type":"uint8"},{"internalType":"address","name":"_address","type":"address"}],"name":"queue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceManagement","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"repayDebtWithAXE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"repayDebtWithReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reserveDepositorQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reserveDepositors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reserveManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reserveSpenderQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reserveSpenders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reserveTokenQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"reserveTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardManagerQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardManagers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sAXE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sAXEQueue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum AxeTreasury.MANAGING","name":"_managing","type":"uint8"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"address","name":"_calculator","type":"address"}],"name":"toggle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"valueOfToken","outputs":[{"internalType":"uint256","name":"value_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]