Feature Tip: Add private address tag to any address under My Name Tag !
ERC-20
Overview
Max Total Supply
1 sINV
Holders
1
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
sINV
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT License pragma solidity ^0.8.21; import "lib/solmate/src/tokens/ERC4626.sol"; interface IInvEscrow { function balance() external view returns (uint); function claimDBR() external; function claimable() external view returns (uint); } interface IMarket { function deposit(uint256 amount) external; function withdraw(uint256 amount) external; function dbr() external returns (address); function escrows(address user) external returns (address); } interface IERC20 { function transfer(address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool); function balanceOf(address) external view returns (uint); } /** * @title sINV * @dev Auto-compounding ERC4626 wrapper for asset FiRM deposits utilizing xy=k auctions. * WARNING: While this vault is safe to be used as collateral in lending markets, it should not be allowed as a borrowable asset. * Any protocol in which sudden, large and atomic increases in the value of an asset may be a security risk should not integrate this vault. */ contract sINV is ERC4626{ struct RevenueData { uint96 periodRevenue; uint96 lastPeriodRevenue; uint64 lastBuyPeriod; } struct KData { uint192 targetK; uint64 lastKUpdate; } uint256 public constant MIN_ASSETS = 10**16; // 1 cent uint256 public constant MIN_SHARES = 10**18; uint256 public constant MAX_ASSETS = 10**32; // 100 trillion asset uint256 public constant period = 7 days; uint256 public depositLimit; IMarket public immutable invMarket; IInvEscrow public immutable invEscrow; ERC20 public immutable DBR; RevenueData public revenueData; KData public kData; address public gov; address public guardian; address public pendingGov; uint256 public minBuffer; uint256 public prevK; function periodRevenue() external view returns(uint256){return revenueData.periodRevenue;} function lastPeriodRevenue() external view returns(uint256){return revenueData.lastPeriodRevenue;} function lastBuyPeriod() external view returns(uint256){return revenueData.lastBuyPeriod;} function targetK() external view returns(uint256){return kData.targetK;} function lastKUpdate() external view returns(uint256){return kData.lastKUpdate;} error OnlyGov(); error OnlyPendingGov(); error OnlyGuardian(); error KTooLow(uint k, uint limit); error BelowMinShares(); error AboveDepositLimit(); error DepositLimitMustIncrease(); error InsufficientAssets(); error Invariant(); error UnauthorizedTokenWithdrawal(); /** * @dev Constructor for sINV contract. * WARNING: MIN_SHARES will always be unwithdrawable from the vault. Deployer should deposit enough to mint MIN_SHARES to avoid causing user grief. * @param _inv Address of the asset token. * @param _invMarket Address of the asset FiRM market. * @param _gov Address of the governance. * @param _K Initial value for the K variable used in calculations. */ constructor( address _inv, address _invMarket, address _gov, address _guardian, uint256 _depositLimit, uint256 _K ) ERC4626(ERC20(_inv), "Staked Inv", "sINV") { if(_K == 0) revert KTooLow(_K, 1); IMarket(_invMarket).deposit(0); //creates an escrow on behalf of the sINV contract invEscrow = IInvEscrow(IMarket(_invMarket).escrows(address(this))); invMarket = IMarket(_invMarket); DBR = ERC20(IMarket(_invMarket).dbr()); gov = _gov; guardian = _guardian; kData.targetK = uint192(_K); depositLimit = _depositLimit; prevK = _K; asset.approve(address(invMarket), type(uint).max); } modifier onlyGov() { if(msg.sender != gov) revert OnlyGov(); _; } modifier onlyPendingGov() { if(msg.sender != pendingGov) revert OnlyPendingGov(); _; } modifier onlyGuardian() { if(msg.sender != guardian) revert OnlyGuardian(); _; } /** * @dev Hook that is called after tokens are deposited into the contract. */ function afterDeposit(uint256, uint256) internal override { if(totalSupply < MIN_SHARES) revert BelowMinShares(); if(totalAssets() > depositLimit) revert AboveDepositLimit(); uint256 invBal = asset.balanceOf(address(this)); if(invBal > minBuffer){ invMarket.deposit(invBal - minBuffer); } } /** * @dev Hook that is called before tokens are withdrawn from the contract. * @param assets The amount of assets to withdraw. * @param shares The amount of shares to withdraw */ function beforeWithdraw(uint256 assets, uint256 shares) internal override { uint256 _totalAssets = totalAssets(); if(_totalAssets < assets + MIN_ASSETS) revert InsufficientAssets(); if(totalSupply < shares + MIN_SHARES) revert BelowMinShares(); uint256 invBal = asset.balanceOf(address(this)); if(assets > invBal) { uint256 withdrawAmount = assets - invBal + minBuffer; if(_totalAssets < withdrawAmount){ invMarket.withdraw(assets - invBal); } else { invMarket.withdraw(withdrawAmount); } } } /** * @dev Calculates the total assets controlled by the contract. * Period revenue is distributed linearly over the following week. * @return The total assets in the contract. */ function totalAssets() public view override returns (uint) { uint256 periodsSinceLastBuy = block.timestamp / period - revenueData.lastBuyPeriod; uint256 _lastPeriodRevenue = revenueData.lastPeriodRevenue; uint256 _periodRevenue = revenueData.periodRevenue; uint256 invBal = invEscrow.balance() + asset.balanceOf(address(this)); if(periodsSinceLastBuy > 1){ return invBal < MAX_ASSETS ? invBal : MAX_ASSETS; } else if(periodsSinceLastBuy == 1) { _lastPeriodRevenue = _periodRevenue; _periodRevenue = 0; } uint256 remainingLastRevenue = _lastPeriodRevenue * (period - block.timestamp % period) / period; uint256 lockedRevenue = remainingLastRevenue + _periodRevenue; uint256 actualAssets; if(invBal > lockedRevenue){ actualAssets = invBal - lockedRevenue; } return actualAssets < MAX_ASSETS ? actualAssets : MAX_ASSETS; } function updatePeriodRevenue(uint96 newRevenue) internal { uint256 currentPeriod = block.timestamp / period; if(currentPeriod > revenueData.lastBuyPeriod) { revenueData.lastPeriodRevenue = revenueData.periodRevenue; revenueData.periodRevenue = newRevenue; revenueData.lastBuyPeriod = uint64(currentPeriod); } else { revenueData.periodRevenue += newRevenue; } } /** * @dev Returns the current value of K, which is a weighted average between prevK and kData.targetK. * @return The current value of K. */ function getK() public view returns (uint) { uint256 timeElapsed = block.timestamp - kData.lastKUpdate; if(timeElapsed > period) { return kData.targetK; } uint256 prevWeight = period - timeElapsed; return (prevK * prevWeight + kData.targetK * timeElapsed) / period; } /** * @dev Calculates the asset reserve based on the current DBR reserve. * @return The calculated asset reserve. */ function getInvReserve() public view returns (uint) { return getK() / getDbrReserve(); } /** * @dev Calculates the asset reserve for a given DBR reserve. * @param DBRReserve The DBR reserve value. * @return The calculated asset reserve. */ function getInvReserve(uint256 DBRReserve) public view returns (uint) { return getK() / DBRReserve; } /** * @dev Returns the current DBR reserve as the sum of DBR balance and claimable DBR * @return The current DBR reserve. */ function getDbrReserve() public view returns (uint) { return DBR.balanceOf(address(this)) + invEscrow.claimable(); } /** * @dev Sets a new target K value. * @param _K The new target K value. */ function setTargetK(uint256 _K) external onlyGov { if(_K < getDbrReserve()) revert KTooLow(_K, getDbrReserve()); prevK = getK(); kData.targetK = uint192(_K); kData.lastKUpdate = uint64(block.timestamp); emit SetTargetK(_K); } /** * @notice Set the min buffer * @dev Min buffer is the buffer of INV held by the sINV contract, which can be withdrawn much more cheaply than if they were staked * @param _minBuffer The new min buffer */ function setMinBuffer(uint256 _minBuffer) external onlyGov { minBuffer = _minBuffer; emit SetMinBuffer(_minBuffer); } /** * @dev Allows users to buy DBR with asset. * WARNING: Never expose this directly to a UI as it's likely to cause a loss unless a transaction is executed immediately. * Instead use the sINVHelper function or custom smart contract code. * @param exactInvIn The exact amount of asset to spend. * @param exactDbrOut The exact amount of DBR to receive. * @param to The address that will receive the DBR. */ function buyDBR(uint256 exactInvIn, uint256 exactDbrOut, address to) external { require(exactInvIn <= type(uint96).max, "EXCEED UINT96"); uint256 DBRBalance = DBR.balanceOf(address(this)); if(exactDbrOut > DBRBalance){ invEscrow.claimDBR(); DBRBalance = DBR.balanceOf(address(this)); } else { DBRBalance += invEscrow.claimable(); } uint256 k = getK(); uint256 DBRReserve = DBRBalance - exactDbrOut; uint256 invReserve = k / DBRBalance + exactInvIn; if(invReserve * DBRReserve < k) revert Invariant(); updatePeriodRevenue(uint96(exactInvIn)); asset.transferFrom(msg.sender, address(this), exactInvIn); DBR.transfer(to, exactDbrOut); emit Buy(msg.sender, to, exactInvIn, exactDbrOut); } /** * @notice Sets a new depositLimit. Only callable by guardian. * @dev Deposit limit must always increase * @param _depositLimit The new deposit limit */ function setDepositLimit(uint _depositLimit) external onlyGuardian { if(_depositLimit <= depositLimit) revert DepositLimitMustIncrease(); depositLimit = _depositLimit; } /** * @notice Sets the guardian that can increase the deposit limit. Only callable by governance. * @param _guardian The new guardian. */ function setGuardian(address _guardian) external onlyGov { guardian = _guardian; } /** * @dev Sets a new pending governance address. * @param _gov The address of the new pending governance. */ function setPendingGov(address _gov) external onlyGov { pendingGov = _gov; } /** * @dev Allows the pending governance to accept its role. */ function acceptGov() external onlyPendingGov { gov = pendingGov; pendingGov = address(0); } /** * @dev Allows governance to sweep any ERC20 token from the contract. * @dev Excludes the ability to sweep DBR tokens. * @param token The address of the ERC20 token to sweep. * @param amount The amount of tokens to sweep. * @param to The recipient address of the swept tokens. */ function sweep(address token, uint256 amount, address to) public onlyGov { if(address(DBR) == token || address(asset) == token) revert UnauthorizedTokenWithdrawal(); IERC20(token).transfer(to, amount); } /** * @notice Allows anyone to reapprove inv spending for invMarket */ function reapprove() external { asset.approve(address(invMarket), type(uint).max); } event Buy(address indexed caller, address indexed to, uint256 exactInvIn, uint256 exactDbrOut); event SetTargetK(uint256 newTargetK); event SetMinBuffer(uint256 newMinBuffer); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; import {SafeTransferLib} from "../utils/SafeTransferLib.sol"; import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol"; /// @notice Minimal ERC4626 tokenized Vault implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol) abstract contract ERC4626 is ERC20 { using SafeTransferLib for ERC20; using FixedPointMathLib for uint256; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /*////////////////////////////////////////////////////////////// IMMUTABLES //////////////////////////////////////////////////////////////*/ ERC20 public immutable asset; constructor( ERC20 _asset, string memory _name, string memory _symbol ) ERC20(_name, _symbol, _asset.decimals()) { asset = _asset; } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LOGIC //////////////////////////////////////////////////////////////*/ function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) { // Check for rounding error since we round down in previewDeposit. require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES"); // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) { assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up. // Need to transfer before minting or ERC777s could reenter. asset.safeTransferFrom(msg.sender, address(this), assets); _mint(receiver, shares); emit Deposit(msg.sender, receiver, assets, shares); afterDeposit(assets, shares); } function withdraw( uint256 assets, address receiver, address owner ) public virtual returns (uint256 shares) { shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up. if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } function redeem( uint256 shares, address receiver, address owner ) public virtual returns (uint256 assets) { if (msg.sender != owner) { uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares; } // Check for rounding error since we round down in previewRedeem. require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS"); beforeWithdraw(assets, shares); _burn(owner, shares); emit Withdraw(msg.sender, receiver, owner, assets, shares); asset.safeTransfer(receiver, assets); } /*////////////////////////////////////////////////////////////// ACCOUNTING LOGIC //////////////////////////////////////////////////////////////*/ function totalAssets() public view virtual returns (uint256); function convertToShares(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets()); } function convertToAssets(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply); } function previewDeposit(uint256 assets) public view virtual returns (uint256) { return convertToShares(assets); } function previewMint(uint256 shares) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply); } function previewWithdraw(uint256 assets) public view virtual returns (uint256) { uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero. return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets()); } function previewRedeem(uint256 shares) public view virtual returns (uint256) { return convertToAssets(shares); } /*////////////////////////////////////////////////////////////// DEPOSIT/WITHDRAWAL LIMIT LOGIC //////////////////////////////////////////////////////////////*/ function maxDeposit(address) public view virtual returns (uint256) { return type(uint256).max; } function maxMint(address) public view virtual returns (uint256) { return type(uint256).max; } function maxWithdraw(address owner) public view virtual returns (uint256) { return convertToAssets(balanceOf[owner]); } function maxRedeem(address owner) public view virtual returns (uint256) { return balanceOf[owner]; } /*////////////////////////////////////////////////////////////// INTERNAL HOOKS LOGIC //////////////////////////////////////////////////////////////*/ function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {} function afterDeposit(uint256 assets, uint256 shares) internal virtual {} }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; import {ERC20} from "../tokens/ERC20.sol"; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. /// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller. library SafeTransferLib { /*////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool success; /// @solidity memory-safe-assembly assembly { // Transfer the ETH and store if it succeeded or not. success := call(gas(), to, amount, 0, 0, 0, 0) } require(success, "ETH_TRANSFER_FAILED"); } /*////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( ERC20 token, address from, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 100, 0, 32) ) } require(success, "TRANSFER_FROM_FAILED"); } function safeTransfer( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "TRANSFER_FAILED"); } function safeApprove( ERC20 token, address to, uint256 amount ) internal { bool success; /// @solidity memory-safe-assembly assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata into memory, beginning with the function selector. mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type. success := and( // Set success to whether the call reverted, if not we check it either // returned exactly 1 (can't just be non-zero data), or had no return data. or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())), // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2. // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space. // Counterintuitively, this call must be positioned second to the or() call in the // surrounding and() call or else returndatasize() will be zero during the computation. call(gas(), token, 0, freeMemoryPointer, 68, 0, 32) ) } require(success, "APPROVE_FAILED"); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant MAX_UINT256 = 2**256 - 1; uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // Divide x * y by the denominator. z := div(mul(x, y), denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y)) if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) { revert(0, 0) } // If x * y modulo the denominator is strictly greater than 0, // 1 is added to round up the division of x * y by the denominator. z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Mod x by y. Note this will return // 0 instead of reverting if y is zero. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) { /// @solidity memory-safe-assembly assembly { // Divide x by y. Note this will return // 0 instead of reverting if y is zero. r := div(x, y) } } function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { /// @solidity memory-safe-assembly assembly { // Add 1 to x * y if x % y > 0. Note this will // return 0 instead of reverting if y is zero. z := add(gt(mod(x, y), 0), div(x, y)) } } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/solmate/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_inv","type":"address"},{"internalType":"address","name":"_invMarket","type":"address"},{"internalType":"address","name":"_gov","type":"address"},{"internalType":"address","name":"_guardian","type":"address"},{"internalType":"uint256","name":"_depositLimit","type":"uint256"},{"internalType":"uint256","name":"_K","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AboveDepositLimit","type":"error"},{"inputs":[],"name":"BelowMinShares","type":"error"},{"inputs":[],"name":"DepositLimitMustIncrease","type":"error"},{"inputs":[],"name":"InsufficientAssets","type":"error"},{"inputs":[],"name":"Invariant","type":"error"},{"inputs":[{"internalType":"uint256","name":"k","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"KTooLow","type":"error"},{"inputs":[],"name":"OnlyGov","type":"error"},{"inputs":[],"name":"OnlyGuardian","type":"error"},{"inputs":[],"name":"OnlyPendingGov","type":"error"},{"inputs":[],"name":"UnauthorizedTokenWithdrawal","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"exactInvIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exactDbrOut","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinBuffer","type":"uint256"}],"name":"SetMinBuffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTargetK","type":"uint256"}],"name":"SetTargetK","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DBR","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_ASSETS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_ASSETS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_SHARES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"exactInvIn","type":"uint256"},{"internalType":"uint256","name":"exactDbrOut","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"buyDBR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDbrReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"DBRReserve","type":"uint256"}],"name":"getInvReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInvReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invEscrow","outputs":[{"internalType":"contract IInvEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"invMarket","outputs":[{"internalType":"contract IMarket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kData","outputs":[{"internalType":"uint192","name":"targetK","type":"uint192"},{"internalType":"uint64","name":"lastKUpdate","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastBuyPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastKUpdate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPeriodRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"period","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodRevenue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"prevK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reapprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revenueData","outputs":[{"internalType":"uint96","name":"periodRevenue","type":"uint96"},{"internalType":"uint96","name":"lastPeriodRevenue","type":"uint96"},{"internalType":"uint64","name":"lastBuyPeriod","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositLimit","type":"uint256"}],"name":"setDepositLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_guardian","type":"address"}],"name":"setGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minBuffer","type":"uint256"}],"name":"setMinBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setPendingGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_K","type":"uint256"}],"name":"setTargetK","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61016060405234801562000011575f80fd5b506040516200320538038062003205833981016040819052620000349162000417565b856040518060400160405280600a81526020016929ba30b5b2b21024b73b60b11b8152506040518060400160405280600481526020016339a4a72b60e11b8152508181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000b4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000da919062000482565b5f620000e784826200054b565b506001620000f683826200054b565b5060ff81166080524660a0526200010c62000361565b60c0525050506001600160a01b0390921660e05250505f81900362000152576040516308b6d51360e31b8152600481018290526001602482015260440160405180910390fd5b60405163b6b55f2560e01b81525f60048201526001600160a01b0386169063b6b55f25906024015f604051808303815f87803b15801562000191575f80fd5b505af1158015620001a4573d5f803e3d5ffd5b50506040516323b9185960e11b81523060048201526001600160a01b038816925063477230b291506024016020604051808303815f875af1158015620001ec573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000212919062000613565b6001600160a01b039081166101205285166101008190526040805163c7ed69cd60e01b8152905163c7ed69cd9160048082019260209290919082900301815f875af115801562000264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200028a919062000613565b6001600160a01b0390811661014052600980546001600160a01b031990811687841617909155600a8054909116858316179055600880546001600160c01b0319166001600160c01b0384161790556006839055600d82905560e0516101005160405163095ea7b360e01b815290831660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200032e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200035491906200062f565b50505050505050620006ca565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f60405162000393919062000650565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80516001600160a01b038116811462000412575f80fd5b919050565b5f805f805f8060c087890312156200042d575f80fd5b6200043887620003fb565b95506200044860208801620003fb565b94506200045860408801620003fb565b93506200046860608801620003fb565b92506080870151915060a087015190509295509295509295565b5f6020828403121562000493575f80fd5b815160ff81168114620004a4575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620004d457607f821691505b602082108103620004f357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000546575f81815260208120601f850160051c81016020861015620005215750805b601f850160051c820191505b8181101562000542578281556001016200052d565b5050505b505050565b81516001600160401b03811115620005675762000567620004ab565b6200057f81620005788454620004bf565b84620004f9565b602080601f831160018114620005b5575f84156200059d5750858301515b5f19600386901b1c1916600185901b17855562000542565b5f85815260208120601f198616915b82811015620005e557888601518255948401946001909101908401620005c4565b50858210156200060357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f6020828403121562000624575f80fd5b620004a482620003fb565b5f6020828403121562000640575f80fd5b81518015158114620004a4575f80fd5b5f8083546200065f81620004bf565b600182811680156200067a57600181146200069057620006be565b60ff1984168752821515830287019450620006be565b875f526020805f205f5b85811015620006b55781548a8201529084019082016200069a565b50505082870194505b50929695505050505050565b60805160a05160c05160e051610100516101205161014051612a48620007bd5f395f8181610607015281816110b7015281816112e8015281816113e4015281816116090152611cf501525f81816108b4015281816109eb0152818161102401528181611365015261146001525f818161049c01528181611c22015281816121a60152818161241701526124ac01525f81816105580152818161098001528181610e8e0152818161119801528181611570015281816117c50152818161190c01528181611c5101528181611d3001528181612127015261236f01525f610e0701525f610dd201525f6105170152612a485ff3fe608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b491906125ee565b6103aa6103e0366004612639565b610bd7565b6103f86103f3366004612639565b610c03565b005b61040d61040836600461266b565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612639565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa670de0b6b3a764000081565b61040d6104db366004612693565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa6105883660046126cc565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612639565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa6106373660046126e5565b610e33565b6103aa61064a3660046126cc565b60036020525f908152604090205481565b6103f8610669366004612639565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126cc565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126cc565b611132565b6103aa6106ec3660046126e5565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d61077236600461266b565b611227565b6103f861078536600461270f565b61128a565b6103aa610798366004612639565b6116c4565b6103aa6107ab366004612741565b6116e2565b6103aa6107be366004612741565b6117ec565b6103f86107d1366004612639565b611933565b6103aa6107e4366004612639565b611985565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126cc565b6119a4565b6103aa610822366004612639565b6119c5565b6103f8610835366004612771565b6119d9565b6103f8611c0b565b6103aa6108503660046126cc565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127de565b611cbe565b6103aa61088b36600461280e565b600460209081525f928352604080842090915290825290205481565b6103aa611dee565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa60065481565b6103aa611e09565b6103aa62093a8081565b6103aa6108ff366004612639565b611e9f565b6103f86109123660046126cc565b611ea9565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261285e565b6109469190612871565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e99190612884565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a699190612884565b610a73919061289b565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ae565b610adc9062093a80612871565b610ae690866128c1565b610af0919061285e565b90505f610afd848361289b565b90505f81841115610b1557610b128285612871565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128d8565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ef6565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611f11565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a8382612871565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d75908490612871565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f805160206129f383398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000004614610e0457610dff611f34565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b5f610cd082610bd7565b5f610e3d83611e9f565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611fcc565b610ec08282612064565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd083826120bb565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611e09565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a29190612884565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111289190612884565b610dff919061289b565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611fcc565b6111ca8284612064565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd081846120bb565b60018054610b58906128d8565b335f90815260036020526040812080548391908390611247908490612871565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f805160206129f383398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113599190612884565b90508083111561145e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114579190612884565b90506114eb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de9190612884565b6114e8908261289b565b90505b5f6114f4611e09565b90505f6115018584612871565b90505f8661150f858561285e565b611519919061289b565b90508261152683836128c1565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612232565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190612910565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116739190612910565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611f11565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611757576117338282612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61176384826122e8565b61176d8282612512565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168486612571565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611856576118328582612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa81856122e8565b6118b48285612512565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168483612571565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b60065481116119805760405163062b386160e21b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161199c610917565b859190611ef6565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119cf611e09565b610cd0919061285e565b42841015611a295760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a34610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b3c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b725750876001600160a01b0316816001600160a01b0316145b611baf5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611c97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cbb9190612910565b50565b6009546001600160a01b03163314611ce957604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480611d5a5750826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b15611d7857604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611dc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611de89190612910565b50505050565b5f611df7611021565b611dff611e09565b610dff919061285e565b6008545f908190611e2b90600160c01b900467ffffffffffffffff1642612871565b905062093a80811115611e495750506008546001600160c01b031690565b5f611e578262093a80612871565b60085490915062093a8090611e769084906001600160c01b03166128c1565b82600d54611e8491906128c1565b611e8e919061289b565b611e98919061285e565b9250505090565b5f610cd082611985565b6009546001600160a01b03163314611ed457604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611f0a575f80fd5b5091020490565b5f825f190484118302158202611f25575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f64919061292f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061205d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f828254612075919061289b565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f805160206129f383398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120e65760405163b6af011960e01b815260040160405180910390fd5b6006546120f1610917565b1115612110576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612174573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121989190612884565b9050600c5481111561222d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b6b55f25600c54836121e19190612871565b6040518263ffffffff1660e01b81526004016121ff91815260200190565b5f604051808303815f87803b158015612216575f80fd5b505af1158015612228573d5f803e3d5ffd5b505050505b505050565b5f61224062093a804261285e565b600754909150600160c01b900467ffffffffffffffff168111156122a3576007805467ffffffffffffffff8316600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b16918516919091171790555050565b600780548391905f906122c09084906001600160601b03166129cb565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b5f6122f1610917565b9050612304662386f26fc100008461289b565b811015612324576040516396d8043360e01b815260040160405180910390fd5b612336670de0b6b3a76400008361289b565b60025410156123585760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156123bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e09190612884565b905080841115611de857600c545f906123f98387612871565b612403919061289b565b905080831015612496576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d6124468488612871565b6040518263ffffffff1660e01b815260040161246491815260200190565b5f604051808303815f87803b15801561247b575f80fd5b505af115801561248d573d5f803e3d5ffd5b5050505061205d565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156124f5575f80fd5b505af1158015612507573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f9081526003602052604081208054839290612539908490612871565b90915550506002805482900390556040518181525f906001600160a01b038416905f805160206129f3833981519152906020016120af565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611de85760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b81811015612619578581018301518582016040015282016125fd565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612649575f80fd5b5035919050565b80356001600160a01b0381168114612666575f80fd5b919050565b5f806040838503121561267c575f80fd5b61268583612650565b946020939093013593505050565b5f805f606084860312156126a5575f80fd5b6126ae84612650565b92506126bc60208501612650565b9150604084013590509250925092565b5f602082840312156126dc575f80fd5b610bfc82612650565b5f80604083850312156126f6575f80fd5b8235915061270660208401612650565b90509250929050565b5f805f60608486031215612721575f80fd5b833592506020840135915061273860408501612650565b90509250925092565b5f805f60608486031215612753575f80fd5b8335925061276360208501612650565b915061273860408501612650565b5f805f805f805f60e0888a031215612787575f80fd5b61279088612650565b965061279e60208901612650565b95506040880135945060608801359350608088013560ff811681146127c1575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156127f0575f80fd5b6127f984612650565b92506020840135915061273860408501612650565b5f806040838503121561281f575f80fd5b61282883612650565b915061270660208401612650565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261286c5761286c612836565b500490565b81810381811115610cd057610cd061284a565b5f60208284031215612894575f80fd5b5051919050565b80820180821115610cd057610cd061284a565b5f826128bc576128bc612836565b500690565b8082028115828204841417610cd057610cd061284a565b600181811c908216806128ec57607f821691505b60208210810361290a57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612920575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061294a57607f831692505b6020808410820361296957634e487b7160e01b86526022600452602486fd5b81801561297d5760018114612992576129bd565b60ff19861689528415158502890196506129bd565b5f8a8152602090205f5b868110156129b55781548b82015290850190830161299c565b505084890196505b509498975050505050505050565b6001600160601b038181168382160190808211156129eb576129eb61284a565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ac64fd4779813955d236993620cf2ef7c782e9b1323433d4bdc9d80584beb30d64736f6c6343000815003300000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000007dd08b930c64a15497342287480000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b491906125ee565b6103aa6103e0366004612639565b610bd7565b6103f86103f3366004612639565b610c03565b005b61040d61040836600461266b565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612639565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b81565b6103aa670de0b6b3a764000081565b61040d6104db366004612693565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6881565b6103aa6105883660046126cc565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612639565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d71081565b6103aa6106373660046126e5565b610e33565b6103aa61064a3660046126cc565b60036020525f908152604090205481565b6103f8610669366004612639565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126cc565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126cc565b611132565b6103aa6106ec3660046126e5565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d61077236600461266b565b611227565b6103f861078536600461270f565b61128a565b6103aa610798366004612639565b6116c4565b6103aa6107ab366004612741565b6116e2565b6103aa6107be366004612741565b6117ec565b6103f86107d1366004612639565b611933565b6103aa6107e4366004612639565b611985565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126cc565b6119a4565b6103aa610822366004612639565b6119c5565b6103f8610835366004612771565b6119d9565b6103f8611c0b565b6103aa6108503660046126cc565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127de565b611cbe565b6103aa61088b36600461280e565b600460209081525f928352604080842090915290825290205481565b6103aa611dee565b61044c7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac81565b6103aa60065481565b6103aa611e09565b6103aa62093a8081565b6103aa6108ff366004612639565b611e9f565b6103f86109123660046126cc565b611ea9565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261285e565b6109469190612871565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e99190612884565b7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a699190612884565b610a73919061289b565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ae565b610adc9062093a80612871565b610ae690866128c1565b610af0919061285e565b90505f610afd848361289b565b90505f81841115610b1557610b128285612871565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128d8565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128d8565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ef6565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611f11565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a8382612871565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d75908490612871565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f805160206129f383398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000014614610e0457610dff611f34565b905090565b507f6045e987479f1722ac43c9eec26a51ee86e35c3e20d2a5a941cb80ef10e0bfde90565b5f610cd082610bd7565b5f610e3d83611e9f565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333086611fcc565b610ec08282612064565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd083826120bb565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611e09565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a29190612884565b6040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111289190612884565b610dff919061289b565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333084611fcc565b6111ca8284612064565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd081846120bb565b60018054610b58906128d8565b335f90815260036020526040812080548391908390611247908490612871565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f805160206129f383398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113599190612884565b90508083111561145e577f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114579190612884565b90506114eb565b7f0000000000000000000000008ef8b4e428bca13db563844f864df0b7268adbac6001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de9190612884565b6114e8908261289b565b90505b5f6114f4611e09565b90505f6115018584612871565b90505f8661150f858561285e565b611519919061289b565b90508261152683836128c1565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612232565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e29190612910565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d710169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116739190612910565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611f11565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611757576117338282612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61176384826122e8565b61176d8282612512565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68168486612571565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f198114611856576118328582612871565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa81856122e8565b6118b48285612512565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68168483612571565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b60065481116119805760405163062b386160e21b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161199c610917565b859190611ef6565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119cf611e09565b610cd0919061285e565b42841015611a295760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a34610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b3c573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b725750876001600160a01b0316816001600160a01b0316145b611baf5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b811660048301525f1960248301527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68169063095ea7b3906044016020604051808303815f875af1158015611c97573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cbb9190612910565b50565b6009546001600160a01b03163314611ce957604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b03161480611d5a5750826001600160a01b03167f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316145b15611d7857604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611dc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611de89190612910565b50505050565b5f611df7611021565b611dff611e09565b610dff919061285e565b6008545f908190611e2b90600160c01b900467ffffffffffffffff1642612871565b905062093a80811115611e495750506008546001600160c01b031690565b5f611e578262093a80612871565b60085490915062093a8090611e769084906001600160c01b03166128c1565b82600d54611e8491906128c1565b611e8e919061289b565b611e98919061285e565b9250505090565b5f610cd082611985565b6009546001600160a01b03163314611ed457604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611f0a575f80fd5b5091020490565b5f825f190484118302158202611f25575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f64919061292f565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061205d5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f828254612075919061289b565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f805160206129f383398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120e65760405163b6af011960e01b815260040160405180910390fd5b6006546120f1610917565b1115612110576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa158015612174573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121989190612884565b9050600c5481111561222d577f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031663b6b55f25600c54836121e19190612871565b6040518263ffffffff1660e01b81526004016121ff91815260200190565b5f604051808303815f87803b158015612216575f80fd5b505af1158015612228573d5f803e3d5ffd5b505050505b505050565b5f61224062093a804261285e565b600754909150600160c01b900467ffffffffffffffff168111156122a3576007805467ffffffffffffffff8316600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b16918516919091171790555050565b600780548391905f906122c09084906001600160601b03166129cb565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b5f6122f1610917565b9050612304662386f26fc100008461289b565b811015612324576040516396d8043360e01b815260040160405180910390fd5b612336670de0b6b3a76400008361289b565b60025410156123585760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa1580156123bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123e09190612884565b905080841115611de857600c545f906123f98387612871565b612403919061289b565b905080831015612496576001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b16632e1a7d4d6124468488612871565b6040518263ffffffff1660e01b815260040161246491815260200190565b5f604051808303815f87803b15801561247b575f80fd5b505af115801561248d573d5f803e3d5ffd5b5050505061205d565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031690632e1a7d4d906024015f604051808303815f87803b1580156124f5575f80fd5b505af1158015612507573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f9081526003602052604081208054839290612539908490612871565b90915550506002805482900390556040518181525f906001600160a01b038416905f805160206129f3833981519152906020016120af565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611de85760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b81811015612619578581018301518582016040015282016125fd565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612649575f80fd5b5035919050565b80356001600160a01b0381168114612666575f80fd5b919050565b5f806040838503121561267c575f80fd5b61268583612650565b946020939093013593505050565b5f805f606084860312156126a5575f80fd5b6126ae84612650565b92506126bc60208501612650565b9150604084013590509250925092565b5f602082840312156126dc575f80fd5b610bfc82612650565b5f80604083850312156126f6575f80fd5b8235915061270660208401612650565b90509250929050565b5f805f60608486031215612721575f80fd5b833592506020840135915061273860408501612650565b90509250925092565b5f805f60608486031215612753575f80fd5b8335925061276360208501612650565b915061273860408501612650565b5f805f805f805f60e0888a031215612787575f80fd5b61279088612650565b965061279e60208901612650565b95506040880135945060608801359350608088013560ff811681146127c1575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f606084860312156127f0575f80fd5b6127f984612650565b92506020840135915061273860408501612650565b5f806040838503121561281f575f80fd5b61282883612650565b915061270660208401612650565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261286c5761286c612836565b500490565b81810381811115610cd057610cd061284a565b5f60208284031215612894575f80fd5b5051919050565b80820180821115610cd057610cd061284a565b5f826128bc576128bc612836565b500690565b8082028115828204841417610cd057610cd061284a565b600181811c908216806128ec57607f821691505b60208210810361290a57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612920575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061294a57607f831692505b6020808410820361296957634e487b7160e01b86526022600452602486fd5b81801561297d5760018114612992576129bd565b60ff19861689528415158502890196506129bd565b5f8a8152602090205f5b868110156129b55781548b82015290850190830161299c565b505084890196505b509498975050505050505050565b6001600160601b038181168382160190808211156129eb576129eb61284a565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220ac64fd4779813955d236993620cf2ef7c782e9b1323433d4bdc9d80584beb30d64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000007dd08b930c64a15497342287480000000000
-----Decoded View---------------
Arg [0] : _inv (address): 0x41D5D79431A913C4aE7d69a668ecdfE5fF9DFB68
Arg [1] : _invMarket (address): 0xb516247596Ca36bf32876199FBdCaD6B3322330B
Arg [2] : _gov (address): 0x926dF14a23BE491164dCF93f4c468A50ef659D5B
Arg [3] : _guardian (address): 0x4b6c63E6a94ef26E2dF60b89372db2d8e211F1B7
Arg [4] : _depositLimit (uint256): 10000000000000000000000
Arg [5] : _K (uint256): 10960000000000000000000000000000000000000000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68
Arg [1] : 000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b
Arg [2] : 000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b
Arg [3] : 0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b7
Arg [4] : 00000000000000000000000000000000000000000000021e19e0c9bab2400000
Arg [5] : 00000000000000000000000000007dd08b930c64a15497342287480000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.