Feature Tip: Add private address tag to any address under My Name Tag !
ERC-20
Source Code
Overview
Max Total Supply
111,156.9016748820416941 sINV
Holders
68
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
3.950813052375311836 sINVValue
$0.00Loading...
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;
uint256 periodsSinceLastBuy = currentPeriod - revenueData.lastBuyPeriod;
if(periodsSinceLastBuy > 1){
revenueData.lastPeriodRevenue = 0;
revenueData.periodRevenue = newRevenue;
revenueData.lastBuyPeriod = uint64(currentPeriod);
} else if(periodsSinceLastBuy == 1) {
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 {
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
Contract ABI
API[{"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
61016060405234801562000011575f80fd5b506040516200322138038062003221833981016040819052620000349162000417565b856040518060400160405280600a81526020016929ba30b5b2b21024b73b60b11b8152506040518060400160405280600481526020016339a4a72b60e11b8152508181846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000b4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000da919062000482565b5f620000e784826200054b565b506001620000f683826200054b565b5060ff81166080524660a0526200010c62000361565b60c0525050506001600160a01b0390921660e05250505f81900362000152576040516308b6d51360e31b8152600481018290526001602482015260440160405180910390fd5b60405163b6b55f2560e01b81525f60048201526001600160a01b0386169063b6b55f25906024015f604051808303815f87803b15801562000191575f80fd5b505af1158015620001a4573d5f803e3d5ffd5b50506040516323b9185960e11b81523060048201526001600160a01b038816925063477230b291506024016020604051808303815f875af1158015620001ec573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000212919062000613565b6001600160a01b039081166101205285166101008190526040805163c7ed69cd60e01b8152905163c7ed69cd9160048082019260209290919082900301815f875af115801562000264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200028a919062000613565b6001600160a01b0390811661014052600980546001600160a01b031990811687841617909155600a8054909116858316179055600880546001600160c01b0319166001600160c01b0384161790556006839055600d82905560e0516101005160405163095ea7b360e01b815290831660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200032e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200035491906200062f565b50505050505050620006ca565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f60405162000393919062000650565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80516001600160a01b038116811462000412575f80fd5b919050565b5f805f805f8060c087890312156200042d575f80fd5b6200043887620003fb565b95506200044860208801620003fb565b94506200045860408801620003fb565b93506200046860608801620003fb565b92506080870151915060a087015190509295509295509295565b5f6020828403121562000493575f80fd5b815160ff81168114620004a4575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c90821680620004d457607f821691505b602082108103620004f357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000546575f81815260208120601f850160051c81016020861015620005215750805b601f850160051c820191505b8181101562000542578281556001016200052d565b5050505b505050565b81516001600160401b03811115620005675762000567620004ab565b6200057f81620005788454620004bf565b84620004f9565b602080601f831160018114620005b5575f84156200059d5750858301515b5f19600386901b1c1916600185901b17855562000542565b5f85815260208120601f198616915b82811015620005e557888601518255948401946001909101908401620005c4565b50858210156200060357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f6020828403121562000624575f80fd5b620004a482620003fb565b5f6020828403121562000640575f80fd5b81518015158114620004a4575f80fd5b5f8083546200065f81620004bf565b600182811680156200067a57600181146200069057620006be565b60ff1984168752821515830287019450620006be565b875f526020805f205f5b85811015620006b55781548a8201529084019082016200069a565b50505082870194505b50929695505050505050565b60805160a05160c05160e051610100516101205161014051612a64620007bd5f395f8181610607015281816110b7015281816112e8015281816113e4015281816116090152611cd301525f81816108b4015281816109eb0152818161102401528181611365015261146001525f818161049c01528181611c00015281816121840152818161243301526124c801525f81816105580152818161098001528181610e8e0152818161119801528181611570015281816117c50152818161190c01528181611c2f01528181611d0e01528181612105015261238b01525f610e0701525f610dd201525f6105170152612a645ff3fe608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b4919061260a565b6103aa6103e0366004612655565b610bd7565b6103f86103f3366004612655565b610c03565b005b61040d610408366004612687565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612655565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa670de0b6b3a764000081565b61040d6104db3660046126af565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa6105883660046126e8565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612655565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa610637366004612701565b610e33565b6103aa61064a3660046126e8565b60036020525f908152604090205481565b6103f8610669366004612655565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126e8565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126e8565b611132565b6103aa6106ec366004612701565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d610772366004612687565b611227565b6103f861078536600461272b565b61128a565b6103aa610798366004612655565b6116c4565b6103aa6107ab36600461275d565b6116e2565b6103aa6107be36600461275d565b6117ec565b6103f86107d1366004612655565b611933565b6103aa6107e4366004612655565b611963565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126e8565b611982565b6103aa610822366004612655565b6119a3565b6103f861083536600461278d565b6119b7565b6103f8611be9565b6103aa6108503660046126e8565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127fa565b611c9c565b6103aa61088b36600461282a565b600460209081525f928352604080842090915290825290205481565b6103aa611dcc565b61044c7f000000000000000000000000000000000000000000000000000000000000000081565b6103aa60065481565b6103aa611de7565b6103aa62093a8081565b6103aa6108ff366004612655565b611e7d565b6103f86109123660046126e8565b611e87565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261287a565b610946919061288d565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e991906128a0565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6991906128a0565b610a7391906128b7565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ca565b610adc9062093a8061288d565b610ae690866128dd565b610af0919061287a565b90505f610afd84836128b7565b90505f81841115610b1557610b12828561288d565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128f4565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ed4565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611eef565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a838261288d565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d7590849061288d565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f80516020612a0f83398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000004614610e0457610dff611f12565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b5f610cd082610bd7565b5f610e3d83611e7d565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086611faa565b610ec08282612042565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd08382612099565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611de7565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a291906128a0565b6040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112891906128a0565b610dff91906128b7565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084611faa565b6111ca8284612042565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd08184612099565b60018054610b58906128f4565b335f9081526003602052604081208054839190839061124790849061288d565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f80516020612a0f83398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135991906128a0565b90508083111561145e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145791906128a0565b90506114eb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de91906128a0565b6114e890826128b7565b90505b5f6114f4611de7565b90505f611501858461288d565b90505f8661150f858561287a565b61151991906128b7565b90508261152683836128dd565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612210565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e2919061292c565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611673919061292c565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611eef565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f19811461175757611733828261288d565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b6117638482612304565b61176d828261252e565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848661258d565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f19811461185657611832858261288d565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa8185612304565b6118b4828561252e565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848361258d565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161197a610917565b859190611ed4565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119ad611de7565b610cd0919061287a565b42841015611a075760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a12610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b1a573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b505750876001600160a01b0316816001600160a01b0316145b611b8d5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301525f1960248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611c75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c99919061292c565b50565b6009546001600160a01b03163314611cc757604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161480611d385750826001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316145b15611d5657604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611da2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dc6919061292c565b50505050565b5f611dd5611021565b611ddd611de7565b610dff919061287a565b6008545f908190611e0990600160c01b900467ffffffffffffffff164261288d565b905062093a80811115611e275750506008546001600160c01b031690565b5f611e358262093a8061288d565b60085490915062093a8090611e549084906001600160c01b03166128dd565b82600d54611e6291906128dd565b611e6c91906128b7565b611e76919061287a565b9250505090565b5f610cd082611963565b6009546001600160a01b03163314611eb257604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611ee8575f80fd5b5091020490565b5f825f190484118302158202611f03575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f42919061294b565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061203b5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f82825461205391906128b7565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f80516020612a0f83398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120c45760405163b6af011960e01b815260040160405180910390fd5b6006546120cf610917565b11156120ee576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612152573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217691906128a0565b9050600c5481111561220b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b6b55f25600c54836121bf919061288d565b6040518263ffffffff1660e01b81526004016121dd91815260200190565b5f604051808303815f87803b1580156121f4575f80fd5b505af1158015612206573d5f803e3d5ffd5b505050505b505050565b5f61221e62093a804261287a565b6007549091505f9061224190600160c01b900467ffffffffffffffff168361288d565b905060018111156122705767ffffffffffffffff8216600160c01b026001600160601b03841617600755505050565b806001036122be576007805467ffffffffffffffff8416600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b1691861691909117179055505050565b600780548491905f906122db9084906001600160601b03166129e7565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550505050565b5f61230d610917565b9050612320662386f26fc10000846128b7565b811015612340576040516396d8043360e01b815260040160405180910390fd5b612352670de0b6b3a7640000836128b7565b60025410156123745760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156123d8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123fc91906128a0565b905080841115611dc657600c545f90612415838761288d565b61241f91906128b7565b9050808310156124b2576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d612462848861288d565b6040518263ffffffff1660e01b815260040161248091815260200190565b5f604051808303815f87803b158015612497575f80fd5b505af11580156124a9573d5f803e3d5ffd5b5050505061203b565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612511575f80fd5b505af1158015612523573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f908152600360205260408120805483929061255590849061288d565b90915550506002805482900390556040518181525f906001600160a01b038416905f80516020612a0f8339815191529060200161208d565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611dc65760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b8181101561263557858101830151858201604001528201612619565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612665575f80fd5b5035919050565b80356001600160a01b0381168114612682575f80fd5b919050565b5f8060408385031215612698575f80fd5b6126a18361266c565b946020939093013593505050565b5f805f606084860312156126c1575f80fd5b6126ca8461266c565b92506126d86020850161266c565b9150604084013590509250925092565b5f602082840312156126f8575f80fd5b610bfc8261266c565b5f8060408385031215612712575f80fd5b823591506127226020840161266c565b90509250929050565b5f805f6060848603121561273d575f80fd5b83359250602084013591506127546040850161266c565b90509250925092565b5f805f6060848603121561276f575f80fd5b8335925061277f6020850161266c565b91506127546040850161266c565b5f805f805f805f60e0888a0312156127a3575f80fd5b6127ac8861266c565b96506127ba6020890161266c565b95506040880135945060608801359350608088013560ff811681146127dd575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f6060848603121561280c575f80fd5b6128158461266c565b9250602084013591506127546040850161266c565b5f806040838503121561283b575f80fd5b6128448361266c565b91506127226020840161266c565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261288857612888612852565b500490565b81810381811115610cd057610cd0612866565b5f602082840312156128b0575f80fd5b5051919050565b80820180821115610cd057610cd0612866565b5f826128d8576128d8612852565b500690565b8082028115828204841417610cd057610cd0612866565b600181811c9082168061290857607f821691505b60208210810361292657634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561293c575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061296657607f831692505b6020808410820361298557634e487b7160e01b86526022600452602486fd5b81801561299957600181146129ae576129d9565b60ff19861689528415158502890196506129d9565b5f8a8152602090205f5b868110156129d15781548b8201529085019083016129b8565b505084890196505b509498975050505050505050565b6001600160601b03818116838216019080821115612a0757612a07612866565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122044b93e02b1a4f6715ea137e1c03f04dd8442eecbaffecd723f158b5d012f7a5464736f6c6343000815003300000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000008e58532b0a48be0067ccbc8dd80000000000
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061039e575f3560e01c80637bc6729b116101ea578063c6e6f59211610114578063dd62ed3e116100a9578063ee39e7a011610079578063ee39e7a0146108df578063ef78d4fd146108e7578063ef8b30f7146108f1578063efdf0bb014610904575f80fd5b8063dd62ed3e1461087d578063e1e59849146108a7578063eba872a7146108af578063ecf70858146108d6575f80fd5b8063d505accf116100e4578063d505accf14610827578063d818f23a1461083a578063d905777e14610842578063dc2c256f1461086a575f80fd5b8063c6e6f592146107d6578063cd153866146107e9578063ce96cb7714610801578063d0926e2614610814575f80fd5b8063a08b06db1161018a578063b460af941161015a578063b460af941461079d578063ba087652146107b0578063bdc8144b146107c3578063c63d75b61461057a575f80fd5b8063a08b06db1461075b578063a9059cbb14610764578063b23adea614610777578063b3d7f6b91461078a575f80fd5b80638a0dac4a116101c55780638a0dac4a146106cb57806394bf804d146106de57806394f5c9dc146106f157806395d89b4114610753575f80fd5b80637bc6729b1461069c5780637ecebe00146106a457806387a64c01146106c3575f80fd5b8063260a220b116102cb5780634cdad5061161026b57806370a082311161023b57806370a082311461063c5780637153a20d1461065b57806376b1d08f1461066e578063781f56de14610683575f80fd5b80634cdad506146105a1578063563e1709146105b45780636d124715146106025780636e553f6514610629575f80fd5b80633644e515116102a65780633644e5151461054b57806338d52e0f14610553578063402d267d1461057a578063452a93201461058e575f80fd5b8063260a220b146104f35780632b8dbaa714610501578063313ce56714610512575f80fd5b806312d43a51116103415780631d2fa930116103115780631d2fa930146104975780631fcd3080146104be57806323b872dd146104cd57806325240810146104e0575f80fd5b806312d43a5114610439578063140c67b21461046457806318160ddd1461047d5780631cd1cf6414610486575f80fd5b8063084219e81161037c578063084219e8146103e5578063095ea7b3146103fa5780630a28a4771461041d57806311e5ff3f14610430575f80fd5b806301e1d114146103a257806306fdde03146103bd57806307a2d13a146103d2575b5f80fd5b6103aa610917565b6040519081526020015b60405180910390f35b6103c5610b4c565b6040516103b4919061260a565b6103aa6103e0366004612655565b610bd7565b6103f86103f3366004612655565b610c03565b005b61040d610408366004612687565b610c6a565b60405190151581526020016103b4565b6103aa61042b366004612655565b610cd6565b6103aa600c5481565b60095461044c906001600160a01b031681565b6040516001600160a01b0390911681526020016103b4565b600754600160c01b900467ffffffffffffffff166103aa565b6103aa60025481565b6008546001600160c01b03166103aa565b61044c7f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b81565b6103aa670de0b6b3a764000081565b61040d6104db3660046126af565b610cf5565b600b5461044c906001600160a01b031681565b6103aa662386f26fc1000081565b6007546001600160601b03166103aa565b6105397f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016103b4565b6103aa610dcf565b61044c7f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6881565b6103aa6105883660046126e8565b505f1990565b600a5461044c906001600160a01b031681565b6103aa6105af366004612655565b610e29565b6008546105da906001600160c01b03811690600160c01b900467ffffffffffffffff1682565b604080516001600160c01b03909316835267ffffffffffffffff9091166020830152016103b4565b61044c7f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d71081565b6103aa610637366004612701565b610e33565b6103aa61064a3660046126e8565b60036020525f908152604090205481565b6103f8610669366004612655565b610f10565b6103aa6d04ee2d6d415b85acef810000000081565b600854600160c01b900467ffffffffffffffff166103aa565b6103f8610fcf565b6103aa6106b23660046126e8565b60056020525f908152604090205481565b6103aa611021565b6103f86106d93660046126e8565b611132565b6103aa6106ec366004612701565b61117f565b600754610723906001600160601b0380821691600160601b810490911690600160c01b900467ffffffffffffffff1683565b604080516001600160601b03948516815293909216602084015267ffffffffffffffff16908201526060016103b4565b6103c561121a565b6103aa600d5481565b61040d610772366004612687565b611227565b6103f861078536600461272b565b61128a565b6103aa610798366004612655565b6116c4565b6103aa6107ab36600461275d565b6116e2565b6103aa6107be36600461275d565b6117ec565b6103f86107d1366004612655565b611933565b6103aa6107e4366004612655565b611963565b600754600160601b90046001600160601b03166103aa565b6103aa61080f3660046126e8565b611982565b6103aa610822366004612655565b6119a3565b6103f861083536600461278d565b6119b7565b6103f8611be9565b6103aa6108503660046126e8565b6001600160a01b03165f9081526003602052604090205490565b6103f86108783660046127fa565b611c9c565b6103aa61088b36600461282a565b600460209081525f928352604080842090915290825290205481565b6103aa611dcc565b61044c7f0000000000000000000000005d2062751a100b384215af7dbacd49398d12094381565b6103aa60065481565b6103aa611de7565b6103aa62093a8081565b6103aa6108ff366004612655565b611e7d565b6103f86109123660046126e8565b611e87565b6007545f908190600160c01b900467ffffffffffffffff1661093c62093a804261287a565b610946919061288d565b6007546040516370a0823160e01b81523060048201529192506001600160601b03600160601b82048116929116905f906001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816906370a0823190602401602060405180830381865afa1580156109c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109e991906128a0565b7f0000000000000000000000005d2062751a100b384215af7dbacd49398d1209436001600160a01b031663b69ef8a86040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6991906128a0565b610a7391906128b7565b90506001841115610ab2576d04ee2d6d415b85acef81000000008110610aa7576d04ee2d6d415b85acef8100000000610aa9565b805b94505050505090565b83600103610ac0579091505f905b5f62093a80610acf81426128ca565b610adc9062093a8061288d565b610ae690866128dd565b610af0919061287a565b90505f610afd84836128b7565b90505f81841115610b1557610b12828561288d565b90505b6d04ee2d6d415b85acef81000000008110610b3e576d04ee2d6d415b85acef8100000000610b40565b805b97505050505050505090565b5f8054610b58906128f4565b80601f0160208091040260200160405190810160405280929190818152602001828054610b84906128f4565b8015610bcf5780601f10610ba657610100808354040283529160200191610bcf565b820191905f5260205f20905b815481529060010190602001808311610bb257829003601f168201915b505050505081565b6002545f908015610bfa57610bf5610bed610917565b849083611ed4565b610bfc565b825b9392505050565b6009546001600160a01b03163314610c2e57604051639097750360e01b815260040160405180910390fd5b600c8190556040518181527fc4ac55c04bc11a90cd33d7e0088129e6985b44c5d85a9f0acdeae027bfeeb50b906020015b60405180910390a150565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610cc49086815260200190565b60405180910390a35060015b92915050565b6002545f908015610bfa57610bf581610ced610917565b859190611eef565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f198114610d4e57610d2a838261288d565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f9081526003602052604081208054859290610d7590849061288d565b90915550506001600160a01b038085165f81815260036020526040908190208054870190555190918716905f80516020612a0f83398151915290610dbc9087815260200190565b60405180910390a3506001949350505050565b5f7f00000000000000000000000000000000000000000000000000000000000000014614610e0457610dff611f12565b905090565b507f8d815ddb6b5e2f83ce08f3938845dbfb205a99747e087b60b1a20afe981d2d4b90565b5f610cd082610bd7565b5f610e3d83611e7d565b9050805f03610e815760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f53484152455360a81b60448201526064015b60405180910390fd5b610eb66001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333086611faa565b610ec08282612042565b60408051848152602081018390526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd08382612099565b6009546001600160a01b03163314610f3b57604051639097750360e01b815260040160405180910390fd5b610f43611021565b811015610f755780610f53611021565b6040516308b6d51360e31b815260048101929092526024820152604401610e78565b610f7d611de7565b600d556001600160c01b038116600160c01b4267ffffffffffffffff1602176008556040518181527f1fcc9c54f3c93fdac0b3691c0d36d64d222420c5ca56c6f1f28b43ab09cb8b7b90602001610c5f565b600b546001600160a01b03163314610ffa576040516307b70d3960e11b815260040160405180910390fd5b600b8054600980546001600160a01b03199081166001600160a01b03841617909155169055565b5f7f0000000000000000000000005d2062751a100b384215af7dbacd49398d1209436001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa15801561107e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110a291906128a0565b6040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611104573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061112891906128a0565b610dff91906128b7565b6009546001600160a01b0316331461115d57604051639097750360e01b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b5f611189836116c4565b90506111c06001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816333084611faa565b6111ca8284612042565b60408051828152602081018590526001600160a01b0384169133917fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7910160405180910390a3610cd08184612099565b60018054610b58906128f4565b335f9081526003602052604081208054839190839061124790849061288d565b90915550506001600160a01b0383165f81815260036020526040908190208054850190555133905f80516020612a0f83398151915290610cc49086815260200190565b6001600160601b038311156112d15760405162461bcd60e51b815260206004820152600d60248201526c22ac21a2a2a2102aa4a72a1c9b60991b6044820152606401610e78565b6040516370a0823160e01b81523060048201525f907f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b0316906370a0823190602401602060405180830381865afa158015611335573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135991906128a0565b90508083111561145e577f0000000000000000000000005d2062751a100b384215af7dbacd49398d1209436001600160a01b031663c93f304e6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156113bb575f80fd5b505af11580156113cd573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b031692506370a082319150602401602060405180830381865afa158015611433573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061145791906128a0565b90506114eb565b7f0000000000000000000000005d2062751a100b384215af7dbacd49398d1209436001600160a01b031663af38d7576040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114ba573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114de91906128a0565b6114e890826128b7565b90505b5f6114f4611de7565b90505f611501858461288d565b90505f8661150f858561287a565b61151991906128b7565b90508261152683836128dd565b101561154557604051633876c51d60e11b815260040160405180910390fd5b61154e87612210565b6040516323b872dd60e01b8152336004820152306024820152604481018890527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906323b872dd906064016020604051808303815f875af11580156115be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115e2919061292c565b5060405163a9059cbb60e01b81526001600160a01b038681166004830152602482018890527f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d710169063a9059cbb906044016020604051808303815f875af115801561164f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611673919061292c565b5060408051888152602081018890526001600160a01b0387169133917f89f5adc174562e07c9c9b1cae7109bbecb21cf9d1b2847e550042b8653c54a0e91015b60405180910390a350505050505050565b6002545f908015610bfa57610bf56116da610917565b849083611eef565b5f6116ec84610cd6565b9050336001600160a01b03831614611759576001600160a01b0382165f9081526004602090815260408083203384529091529020545f19811461175757611733828261288d565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b6117638482612304565b61176d828261252e565b60408051858152602081018390526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816848661258d565b5f336001600160a01b03831614611858576001600160a01b0382165f9081526004602090815260408083203384529091529020545f19811461185657611832858261288d565b6001600160a01b0384165f9081526004602090815260408083203384529091529020555b505b61186184610e29565b9050805f036118a05760405162461bcd60e51b815260206004820152600b60248201526a5a45524f5f41535345545360a81b6044820152606401610e78565b6118aa8185612304565b6118b4828561252e565b60408051828152602081018690526001600160a01b03808516929086169133917ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db910160405180910390a4610bfc6001600160a01b037f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb6816848361258d565b600a546001600160a01b0316331461195e57604051636570ecab60e11b815260040160405180910390fd5b600655565b6002545f908015610bfa57610bf58161197a610917565b859190611ed4565b6001600160a01b0381165f90815260036020526040812054610cd090610bd7565b5f816119ad611de7565b610cd0919061287a565b42841015611a075760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610e78565b5f6001611a12610dcf565b6001600160a01b038a81165f8181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f1981840301815282825280516020918201205f84529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015611b1a573d5f803e3d5ffd5b5050604051601f1901519150506001600160a01b03811615801590611b505750876001600160a01b0316816001600160a01b0316145b611b8d5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610e78565b6001600160a01b039081165f9081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591016116b3565b60405163095ea7b360e01b81526001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b811660048301525f1960248301527f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68169063095ea7b3906044016020604051808303815f875af1158015611c75573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c99919061292c565b50565b6009546001600160a01b03163314611cc757604051639097750360e01b815260040160405180910390fd5b826001600160a01b03167f000000000000000000000000ad038eb671c44b853887a7e32528fab35dc5d7106001600160a01b03161480611d385750826001600160a01b03167f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316145b15611d5657604051631b16270360e01b815260040160405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb906044016020604051808303815f875af1158015611da2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611dc6919061292c565b50505050565b5f611dd5611021565b611ddd611de7565b610dff919061287a565b6008545f908190611e0990600160c01b900467ffffffffffffffff164261288d565b905062093a80811115611e275750506008546001600160c01b031690565b5f611e358262093a8061288d565b60085490915062093a8090611e549084906001600160c01b03166128dd565b82600d54611e6291906128dd565b611e6c91906128b7565b611e76919061287a565b9250505090565b5f610cd082611963565b6009546001600160a01b03163314611eb257604051639097750360e01b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b5f825f190484118302158202611ee8575f80fd5b5091020490565b5f825f190484118302158202611f03575f80fd5b50910281810615159190040190565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f5f604051611f42919061294b565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b5f6040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260205f6064835f8a5af13d15601f3d1160015f51141617169150508061203b5760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610e78565b5050505050565b8060025f82825461205391906128b7565b90915550506001600160a01b0382165f818152600360209081526040808320805486019055518481525f80516020612a0f83398151915291015b60405180910390a35050565b670de0b6b3a764000060025410156120c45760405163b6af011960e01b815260040160405180910390fd5b6006546120cf610917565b11156120ee576040516301d8a97b60e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa158015612152573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061217691906128a0565b9050600c5481111561220b577f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031663b6b55f25600c54836121bf919061288d565b6040518263ffffffff1660e01b81526004016121dd91815260200190565b5f604051808303815f87803b1580156121f4575f80fd5b505af1158015612206573d5f803e3d5ffd5b505050505b505050565b5f61221e62093a804261287a565b6007549091505f9061224190600160c01b900467ffffffffffffffff168361288d565b905060018111156122705767ffffffffffffffff8216600160c01b026001600160601b03841617600755505050565b806001036122be576007805467ffffffffffffffff8416600160c01b02600160601b6001600160601b03928316026bffffffffffffffffffffffff60601b1691861691909117179055505050565b600780548491905f906122db9084906001600160601b03166129e7565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550505050565b5f61230d610917565b9050612320662386f26fc10000846128b7565b811015612340576040516396d8043360e01b815260040160405180910390fd5b612352670de0b6b3a7640000836128b7565b60025410156123745760405163b6af011960e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f907f00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb686001600160a01b0316906370a0823190602401602060405180830381865afa1580156123d8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123fc91906128a0565b905080841115611dc657600c545f90612415838761288d565b61241f91906128b7565b9050808310156124b2576001600160a01b037f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b16632e1a7d4d612462848861288d565b6040518263ffffffff1660e01b815260040161248091815260200190565b5f604051808303815f87803b158015612497575f80fd5b505af11580156124a9573d5f803e3d5ffd5b5050505061203b565b604051632e1a7d4d60e01b8152600481018290527f000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b6001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015612511575f80fd5b505af1158015612523573d5f803e3d5ffd5b505050505050505050565b6001600160a01b0382165f908152600360205260408120805483929061255590849061288d565b90915550506002805482900390556040518181525f906001600160a01b038416905f80516020612a0f8339815191529060200161208d565b5f60405163a9059cbb60e01b81526001600160a01b038416600482015282602482015260205f6044835f895af13d15601f3d1160015f511416171691505080611dc65760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610e78565b5f6020808352835180828501525f5b8181101561263557858101830151858201604001528201612619565b505f604082860101526040601f19601f8301168501019250505092915050565b5f60208284031215612665575f80fd5b5035919050565b80356001600160a01b0381168114612682575f80fd5b919050565b5f8060408385031215612698575f80fd5b6126a18361266c565b946020939093013593505050565b5f805f606084860312156126c1575f80fd5b6126ca8461266c565b92506126d86020850161266c565b9150604084013590509250925092565b5f602082840312156126f8575f80fd5b610bfc8261266c565b5f8060408385031215612712575f80fd5b823591506127226020840161266c565b90509250929050565b5f805f6060848603121561273d575f80fd5b83359250602084013591506127546040850161266c565b90509250925092565b5f805f6060848603121561276f575f80fd5b8335925061277f6020850161266c565b91506127546040850161266c565b5f805f805f805f60e0888a0312156127a3575f80fd5b6127ac8861266c565b96506127ba6020890161266c565b95506040880135945060608801359350608088013560ff811681146127dd575f80fd5b9699959850939692959460a0840135945060c09093013592915050565b5f805f6060848603121561280c575f80fd5b6128158461266c565b9250602084013591506127546040850161266c565b5f806040838503121561283b575f80fd5b6128448361266c565b91506127226020840161266c565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f8261288857612888612852565b500490565b81810381811115610cd057610cd0612866565b5f602082840312156128b0575f80fd5b5051919050565b80820180821115610cd057610cd0612866565b5f826128d8576128d8612852565b500690565b8082028115828204841417610cd057610cd0612866565b600181811c9082168061290857607f821691505b60208210810361292657634e487b7160e01b5f52602260045260245ffd5b50919050565b5f6020828403121561293c575f80fd5b81518015158114610bfc575f80fd5b5f80835481600182811c91508083168061296657607f831692505b6020808410820361298557634e487b7160e01b86526022600452602486fd5b81801561299957600181146129ae576129d9565b60ff19861689528415158502890196506129d9565b5f8a8152602090205f5b868110156129d15781548b8201529085019083016129b8565b505084890196505b509498975050505050505050565b6001600160601b03818116838216019080821115612a0757612a07612866565b509291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122044b93e02b1a4f6715ea137e1c03f04dd8442eecbaffecd723f158b5d012f7a5464736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b700000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000008e58532b0a48be0067ccbc8dd80000000000
-----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): 12400000000000000000000000000000000000000000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000041d5d79431a913c4ae7d69a668ecdfe5ff9dfb68
Arg [1] : 000000000000000000000000b516247596ca36bf32876199fbdcad6b3322330b
Arg [2] : 000000000000000000000000926df14a23be491164dcf93f4c468a50ef659d5b
Arg [3] : 0000000000000000000000004b6c63e6a94ef26e2df60b89372db2d8e211f1b7
Arg [4] : 00000000000000000000000000000000000000000000021e19e0c9bab2400000
Arg [5] : 00000000000000000000000000008e58532b0a48be0067ccbc8dd80000000000
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.
Add Token to MetaMask (Web3)