Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 6 from a total of 6 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
_set Reserves Ma... | 3393415 | 21 days ago | IN | 0 S | 0.00029065 | ||||
_accept Admin | 3141902 | 23 days ago | IN | 0 S | 0.00022202 | ||||
_set Pending Adm... | 3080064 | 24 days ago | IN | 0 S | 0.00026001 | ||||
Create Vault | 3079791 | 24 days ago | IN | 0 S | 0.02687815 | ||||
Create Vault | 3079779 | 24 days ago | IN | 0 S | 0.02689206 | ||||
Create Vault | 3079760 | 24 days ago | IN | 0 S | 0.02694285 |
Loading...
Loading
Contract Name:
LendingVaultV1Factory
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity =0.5.16; import "./LVDeployerV1.sol"; import "./interfaces/ILendingVaultV1.sol"; import "./interfaces/ILendingVaultV1Factory.sol"; import "./interfaces/IERC20.sol"; import "./libraries/StringHelpers.sol"; contract LendingVaultV1Factory is ILendingVaultV1Factory { using StringHelpers for string; address public admin; address public pendingAdmin; address public reservesAdmin; address public reservesPendingAdmin; address public reservesManager; address[] public allVaults; function allVaultsLength() external view returns (uint) { return allVaults.length; } ILVDeployerV1 public LVDeployerV1; constructor(address _admin, address _reservesAdmin, ILVDeployerV1 _LVDeployerV1) public { admin = _admin; reservesAdmin = _reservesAdmin; LVDeployerV1 = _LVDeployerV1; emit NewAdmin(address(0), _admin); emit NewReservesAdmin(address(0), _reservesAdmin); } function createVault(address underlying, string calldata _name, string calldata _symbol) external returns (address vault) { string memory name = _name.orElse(string("Impermax ").append(IERC20(address(underlying)).symbol()).append(" Lending Vault")); string memory symbol = _symbol.orElse(string("i").append(IERC20(address(underlying)).symbol())); vault = LVDeployerV1.deployVault(); ILendingVaultV1(vault)._setFactory(); ILendingVaultV1(vault)._initialize(underlying, name, symbol); allVaults.push(vault); emit VaultCreated(underlying, vault, allVaults.length); } function _setPendingAdmin(address newPendingAdmin) external { require(msg.sender == admin, "LendingAggregatorV1Factory: UNAUTHORIZED"); address oldPendingAdmin = pendingAdmin; pendingAdmin = newPendingAdmin; emit NewPendingAdmin(oldPendingAdmin, newPendingAdmin); } function _acceptAdmin() external { require(msg.sender == pendingAdmin, "LendingAggregatorV1Factory: UNAUTHORIZED"); address oldAdmin = admin; address oldPendingAdmin = pendingAdmin; admin = pendingAdmin; pendingAdmin = address(0); emit NewAdmin(oldAdmin, admin); emit NewPendingAdmin(oldPendingAdmin, address(0)); } function _setReservesPendingAdmin(address newReservesPendingAdmin) external { require(msg.sender == reservesAdmin, "LendingAggregatorV1Factory: UNAUTHORIZED"); address oldReservesPendingAdmin = reservesPendingAdmin; reservesPendingAdmin = newReservesPendingAdmin; emit NewReservesPendingAdmin(oldReservesPendingAdmin, newReservesPendingAdmin); } function _acceptReservesAdmin() external { require(msg.sender == reservesPendingAdmin, "LendingAggregatorV1Factory: UNAUTHORIZED"); address oldReservesAdmin = reservesAdmin; address oldReservesPendingAdmin = reservesPendingAdmin; reservesAdmin = reservesPendingAdmin; reservesPendingAdmin = address(0); emit NewReservesAdmin(oldReservesAdmin, reservesAdmin); emit NewReservesPendingAdmin(oldReservesPendingAdmin, address(0)); } function _setReservesManager(address newReservesManager) external { require(msg.sender == reservesAdmin, "LendingAggregatorV1Factory: UNAUTHORIZED"); address oldReservesManager = reservesManager; reservesManager = newReservesManager; emit NewReservesManager(oldReservesManager, newReservesManager); } }
pragma solidity =0.5.16; import "./libraries/SafeMath.sol"; // This contract is basically UniswapV2ERC20 with small modifications // src: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol contract ImpermaxERC20 { using SafeMath for uint; string public name; string public symbol; uint8 public decimals = 18; uint public totalSupply; mapping(address => uint) public balanceOf; mapping(address => mapping(address => uint)) public allowance; bytes32 public DOMAIN_SEPARATOR; mapping(address => uint) public nonces; event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); constructor() public {} function _setName(string memory _name, string memory _symbol) internal { name = _name; symbol = _symbol; uint chainId; assembly { chainId := chainid } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(_name)), keccak256(bytes("1")), chainId, address(this) ) ); } function _mint(address to, uint value) internal { totalSupply = totalSupply.add(value); balanceOf[to] = balanceOf[to].add(value); emit Transfer(address(0), to, value); } function _burn(address from, uint value) internal { balanceOf[from] = balanceOf[from].sub(value); totalSupply = totalSupply.sub(value); emit Transfer(from, address(0), value); } function _approve(address owner, address spender, uint value) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer(address from, address to, uint value) internal { balanceOf[from] = balanceOf[from].sub(value, "Impermax: TRANSFER_TOO_HIGH"); balanceOf[to] = balanceOf[to].add(value); emit Transfer(from, to, value); } function approve(address spender, uint value) external returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint value) external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom(address from, address to, uint value) external returns (bool) { if (allowance[from][msg.sender] != uint(-1)) { allowance[from][msg.sender] = allowance[from][msg.sender].sub(value, "Impermax: TRANSFER_NOT_ALLOWED"); } _transfer(from, to, value); return true; } function _checkSignature(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s, bytes32 typehash) internal { require(deadline >= block.timestamp, "Impermax: EXPIRED"); bytes32 digest = keccak256( abi.encodePacked( '\x19\x01', DOMAIN_SEPARATOR, keccak256(abi.encode(typehash, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "Impermax: INVALID_SIGNATURE"); } // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { _checkSignature(owner, spender, value, deadline, v, r, s, PERMIT_TYPEHASH); _approve(owner, spender, value); } }
pragma solidity >=0.5.0; interface IBorrowable { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; /*** Borrowable ***/ event BorrowApproval(address indexed owner, address indexed spender, uint value); event Borrow(address indexed sender, address indexed borrower, address indexed receiver, uint borrowAmount, uint repayAmount, uint accountBorrowsPrior, uint accountBorrows, uint totalBorrows); event Liquidate(address indexed sender, address indexed borrower, address indexed liquidator, uint seizeTokens, uint repayAmount, uint accountBorrowsPrior, uint accountBorrows, uint totalBorrows); function BORROW_FEE() external pure returns (uint); function collateral() external view returns (address); function reserveFactor() external view returns (uint); function exchangeRateLast() external view returns (uint); function borrowIndex() external view returns (uint); function totalBorrows() external view returns (uint); function borrowAllowance(address owner, address spender) external view returns (uint); function borrowBalance(address borrower) external view returns (uint); function borrowTracker() external view returns (address); function BORROW_PERMIT_TYPEHASH() external pure returns (bytes32); function borrowApprove(address spender, uint256 value) external returns (bool); function borrowPermit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; function borrow(address borrower, address receiver, uint borrowAmount, bytes calldata data) external; function liquidate(address borrower, address liquidator) external returns (uint seizeTokens); function trackBorrow(address borrower) external; /*** Borrowable Interest Rate Model ***/ event AccrueInterest(uint interestAccumulated, uint borrowIndex, uint totalBorrows); event CalculateKink(uint kinkRate); event CalculateBorrowRate(uint borrowRate); function KINK_BORROW_RATE_MAX() external pure returns (uint); function KINK_BORROW_RATE_MIN() external pure returns (uint); function KINK_MULTIPLIER() external pure returns (uint); function borrowRate() external view returns (uint); function kinkBorrowRate() external view returns (uint); function kinkUtilizationRate() external view returns (uint); function adjustSpeed() external view returns (uint); function rateUpdateTimestamp() external view returns (uint32); function accrualTimestamp() external view returns (uint32); function accrueInterest() external; /*** Borrowable Setter ***/ event NewReserveFactor(uint newReserveFactor); event NewKinkUtilizationRate(uint newKinkUtilizationRate); event NewAdjustSpeed(uint newAdjustSpeed); event NewBorrowTracker(address newBorrowTracker); function RESERVE_FACTOR_MAX() external pure returns (uint); function KINK_UR_MIN() external pure returns (uint); function KINK_UR_MAX() external pure returns (uint); function ADJUST_SPEED_MIN() external pure returns (uint); function ADJUST_SPEED_MAX() external pure returns (uint); function _initialize ( string calldata _name, string calldata _symbol, address _underlying, address _collateral ) external; function _setReserveFactor(uint newReserveFactor) external; function _setKinkUtilizationRate(uint newKinkUtilizationRate) external; function _setAdjustSpeed(uint newAdjustSpeed) external; function _setBorrowTracker(address newBorrowTracker) external; }
pragma solidity >=0.5.0; interface IERC20 { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); }
pragma solidity >=0.5.0; interface ILendingVaultV1 { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; /*** Lending Vault V1 ***/ event AddBorrowable(address indexed borrowable); event RemoveBorrowable(address indexed borrowable); event EnableBorrowable(address indexed borrowable); event DisableBorrowable(address indexed borrowable); event UnwindBorrowable(address indexed borrowable, uint256 underlyingBalance, uint256 actualRedeemAmount); event AllocateIntoBorrowable(address indexed borrowable, uint256 mintAmount, uint256 mintTokens); event DeallocateFromBorrowable(address indexed borrowable, uint256 redeemAmount, uint256 redeemTokens); function borrowables(uint) external view returns (address borrowable); function borrowableInfo(address borrowable) external view returns ( bool enabled, bool exists ); function getBorrowablesLength() external view returns (uint); function indexOfBorrowable(address borrowable) external view returns (uint); function reserveFactor() external view returns (uint); function exchangeRateLast() external view returns (uint); function addBorrowable(address borrowable) external; function removeBorrowable(address borrowable) external; function disableBorrowable(address borrowable) external; function enableBorrowable(address borrowable) external; function unwindBorrowable(address borrowable) external; function reallocate() external; /*** Lending Vault Setter ***/ event NewReserveFactor(uint newReserveFactor); function RESERVE_FACTOR_MAX() external pure returns (uint); function _initialize ( address _underlying, string calldata _name, string calldata _symbol ) external; function _setReserveFactor(uint newReserveFactor) external; }
pragma solidity >=0.5.0; interface ILendingVaultV1Factory { event VaultCreated(address indexed underlying, address vault, uint); event NewPendingAdmin(address oldPendingAdmin, address newPendingAdmin); event NewAdmin(address oldAdmin, address newAdmin); event NewReservesPendingAdmin(address oldReservesPendingAdmin, address newReservesPendingAdmin); event NewReservesAdmin(address oldReservesAdmin, address newReservesAdmin); event NewReservesManager(address oldReservesManager, address newReservesManager); function admin() external view returns (address); function pendingAdmin() external view returns (address); function reservesAdmin() external view returns (address); function reservesPendingAdmin() external view returns (address); function reservesManager() external view returns (address); function allVaults(uint) external view returns (address); function allVaultsLength() external view returns (uint); function createVault(address underlying, string calldata _name, string calldata _symbol) external returns (address vault); function _setPendingAdmin(address newPendingAdmin) external; function _acceptAdmin() external; function _setReservesPendingAdmin(address newPendingAdmin) external; function _acceptReservesAdmin() external; function _setReservesManager(address newReservesManager) external; }
pragma solidity >=0.5.0; interface ILVDeployerV1 { function deployVault() external returns (address vault); }
pragma solidity >=0.5.0; interface IPoolToken { /*** Impermax ERC20 ***/ event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; /*** Pool Token ***/ event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); function underlying() external view returns (address); function factory() external view returns (address); function totalBalance() external view returns (uint); function MINIMUM_LIQUIDITY() external pure returns (uint); function exchangeRate() external returns (uint); function mint(address minter) external returns (uint mintTokens); function redeem(address redeemer) external returns (uint redeemAmount); function skim(address to) external; function sync() external; function _setFactory() external; }
pragma solidity =0.5.16; import "./LVSetterV1.sol"; import "./interfaces/ILendingVaultV1Factory.sol"; contract LendingVaultV1 is LVSetterV1 { function _getTotalSupplied() internal returns (uint totalSupplied) { for (uint i = 0; i < borrowables.length; i++) { address borrowable = borrowables[i]; totalSupplied = totalSupplied.add(borrowable.myUnderlyingBalance()); } } function _mintReserves(uint _exchangeRate, uint _totalSupply) internal returns (uint) { uint _exchangeRateLast = exchangeRateLast; if (_exchangeRate > _exchangeRateLast) { uint _exchangeRateNew = _exchangeRate.sub( _exchangeRate.sub(_exchangeRateLast).mul(reserveFactor).div(1e18) ); uint liquidity = _totalSupply.mul(_exchangeRate).div(_exchangeRateNew).sub(_totalSupply); if (liquidity > 0) { address reservesManager = ILendingVaultV1Factory(factory).reservesManager(); _mint(reservesManager, liquidity); } exchangeRateLast = _exchangeRateNew; return _exchangeRateNew; } else return _exchangeRate; } function exchangeRate() public returns (uint) { uint _totalSupply = totalSupply; uint _actualBalance = totalBalance.add(_getTotalSupplied()); if (_totalSupply == 0 || _actualBalance == 0) return initialExchangeRate; uint _exchangeRate = _actualBalance.mul(1e18).div(_totalSupply); return _mintReserves(_exchangeRate, _totalSupply); } // this low-level function should be called from another contract function mint(address minter) external nonReentrant update returns (uint mintTokens) { uint balance = underlying.myBalance(); uint mintAmount = balance.sub(totalBalance); mintTokens = mintAmount.mul(1e18).div(exchangeRate()); if(totalSupply == 0) { // permanently lock the first MINIMUM_LIQUIDITY tokens mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); } require(mintTokens > 0, "LendingVaultV1: MINT_AMOUNT_ZERO"); _mint(minter, mintTokens); _withdrawAndReallocate(0); emit Mint(msg.sender, minter, mintAmount, mintTokens); } // this low-level function should be called from another contract function redeem(address redeemer) external nonReentrant update returns (uint redeemAmount) { uint redeemTokens = balanceOf[address(this)]; redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18); require(redeemAmount > 0, "LendingVaultV1: REDEEM_AMOUNT_ZERO"); _burn(address(this), redeemTokens); _withdrawAndReallocate(redeemAmount); underlying.safeTransfer(redeemer, redeemAmount); emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens); } function reallocate() external nonReentrant update { _withdrawAndReallocate(0); } }
pragma solidity =0.5.16; import "./SafeMath.sol"; import "../interfaces/IBorrowable.sol"; import "../interfaces/IERC20.sol"; library BorrowableHelpers { using SafeMath for uint256; function underlyingValueOf(address borrowable, uint256 borrowableAmount) internal returns (uint256) { uint256 exchangeRate = IBorrowable(borrowable).exchangeRate(); return borrowableAmount.mul(exchangeRate).div(1e18); } function underlyingBalanceOf(address borrowable, address account) internal returns (uint256) { return underlyingValueOf(borrowable, IBorrowable(borrowable).balanceOf(account)); } function myUnderlyingBalance(address borrowable) internal returns (uint256) { return underlyingValueOf(borrowable, IBorrowable(borrowable).balanceOf(address(this))); } /*** AMOUNT TO TOKENS CONVERSION ***/ function tokensFor(uint redeemAmount, uint exchangeRate, bool atMost) internal pure returns (uint redeemTokens) { uint redeemTokensLow = redeemAmount.mul(1e18).div(exchangeRate); uint redeemTokensHigh = redeemTokensLow.add(1); if (atMost) { uint actualRedeemAmountHigh = redeemTokensHigh.mul(exchangeRate).div(1e18); return actualRedeemAmountHigh <= redeemAmount ? redeemTokensHigh : redeemTokensLow; } else { uint actualRedeemAmountLow = redeemTokensLow.mul(exchangeRate).div(1e18); return actualRedeemAmountLow >= redeemAmount ? redeemTokensLow : redeemTokensHigh; } } function tokensForAtMost(uint redeemAmount, uint exchangeRate) internal pure returns (uint redeemTokens) { return tokensFor(redeemAmount, exchangeRate, true); } function tokensForAtLeast(uint redeemAmount, uint exchangeRate) internal pure returns (uint redeemTokens) { return tokensFor(redeemAmount, exchangeRate, false); } }
pragma solidity =0.5.16; pragma experimental ABIEncoderV2; import "./SafeMath.sol"; import "./Math.sol"; import "../interfaces/IBorrowable.sol"; library BorrowableObject { using SafeMath for uint; using BorrowableObject for Borrowable; struct Borrowable { IBorrowable borrowableContract; uint exchangeRate; uint totalBorrows; // in underlyings uint externalSupply; // in underlyings uint initialOwnedSupply; // in underlyings uint ownedSupply; // in underlyings uint kinkBorrowRate; uint kinkUtilizationRate; uint reserveFactor; uint kinkMultiplier; uint cachedSupplyRate; } function newBorrowable(IBorrowable borrowableContract, address lendingVault) internal returns (Borrowable memory borrowable) { borrowableContract.sync(); uint exchangeRate = borrowableContract.exchangeRate(); uint totalSupplyInTokens = borrowableContract.totalSupply(); uint ownedSupplyInTokens = borrowableContract.balanceOf(lendingVault); uint externalSupplyInTokens = totalSupplyInTokens.sub(ownedSupplyInTokens); borrowable = Borrowable({ borrowableContract: borrowableContract, exchangeRate: exchangeRate, totalBorrows: borrowableContract.totalBorrows(), externalSupply: externalSupplyInTokens.mul(exchangeRate).div(1e18), initialOwnedSupply: ownedSupplyInTokens.mul(exchangeRate).div(1e18), ownedSupply: ownedSupplyInTokens.mul(exchangeRate).div(1e18), kinkBorrowRate: borrowableContract.kinkBorrowRate(), kinkUtilizationRate: borrowableContract.kinkUtilizationRate(), reserveFactor: borrowableContract.reserveFactor(), kinkMultiplier: borrowableContract.KINK_MULTIPLIER(), cachedSupplyRate: 0 }); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function totalSupply(Borrowable memory borrowable) internal pure returns (uint) { return borrowable.externalSupply.add(borrowable.ownedSupply); } function utilizationRate(Borrowable memory borrowable) internal pure returns (uint) { uint _totalSupply = totalSupply(borrowable); if (_totalSupply == 0) return 0; return borrowable.totalBorrows.mul(1e18).div(_totalSupply); } function kinkRate(Borrowable memory borrowable) internal pure returns (uint) { return borrowable.kinkUtilizationRate .mul(borrowable.kinkBorrowRate).div(1e18) .mul(uint(1e18).sub(borrowable.reserveFactor)).div(1e18); } function supplyRate(Borrowable memory borrowable) internal pure returns (uint rate) { uint utilizationRate_ = utilizationRate(borrowable); uint ratio = utilizationRate_.mul(1e18).div(borrowable.kinkUtilizationRate); uint borrowFactor; //borrowRate to kinkBorrowRate ratio if (utilizationRate_ < borrowable.kinkUtilizationRate) { borrowFactor = ratio; } else { uint excessRatio = utilizationRate_.sub(borrowable.kinkUtilizationRate) .mul(1e18).div(uint(1e18).sub(borrowable.kinkUtilizationRate)); borrowFactor = excessRatio.mul(borrowable.kinkMultiplier.sub(1)).add(1e18); } rate = borrowFactor.mul(kinkRate(borrowable)).div(1e18).mul(ratio).div(1e18); } function allocate(Borrowable memory borrowable, uint amount) internal pure returns (Borrowable memory) { borrowable.ownedSupply = borrowable.ownedSupply.add(amount); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function deallocate(Borrowable memory borrowable, uint amount) internal pure returns (Borrowable memory) { uint availableLiquidity = totalSupply(borrowable).sub(borrowable.totalBorrows, "ERROR: NEGATIVE AVAILABLE LIQUIDITY"); require(amount <= availableLiquidity, "ERROR: DEALLOCATE AMOUNT > AVAILABLE LIQUIDITY"); borrowable.ownedSupply = borrowable.ownedSupply.sub(amount); borrowable.cachedSupplyRate = supplyRate(borrowable); return borrowable; } function deallocateMax(Borrowable memory borrowable) internal pure returns (Borrowable memory, uint) { if (totalSupply(borrowable) < borrowable.totalBorrows) return (borrowable, 0); uint availableLiquidity = totalSupply(borrowable).sub(borrowable.totalBorrows); uint amount = Math.min(borrowable.ownedSupply, availableLiquidity); return (deallocate(borrowable, amount), amount); } function calculateUtilizationForRate(Borrowable memory borrowable, uint rate) internal pure returns (uint targetUtilizationRate) { if (rate <= kinkRate(borrowable)) { targetUtilizationRate = Math.sqrt( rate.mul(1e18).div(kinkRate(borrowable)).mul(1e18) ).mul(borrowable.kinkUtilizationRate).div(1e18); } else { uint a = borrowable.kinkMultiplier.sub(1); uint b = borrowable.kinkUtilizationRate.mul(borrowable.kinkMultiplier).sub(1e18); uint c = rate.mul(borrowable.kinkUtilizationRate).div(1e18) .mul(uint(1e18).sub(borrowable.kinkUtilizationRate)).div(kinkRate(borrowable)); uint tmp = Math.sqrt( b.mul(b).div(1e18).add(a.mul(c).mul(4)).mul(1e18) ); targetUtilizationRate = tmp.add(b).div(a).div(2); } require(targetUtilizationRate <= 1e18, "ERROR: TARGET UTILIZATION > 100%"); } function calculateAmountForRate(Borrowable memory borrowable, uint rate) internal pure returns (uint) { require(rate > 0, "ERROR: rate = 0"); require(rate <= borrowable.cachedSupplyRate, "ERROR: TARGET RATE > CACHED RATE"); uint targetUtilizationRate = calculateUtilizationForRate(borrowable, rate); require(targetUtilizationRate <= utilizationRate(borrowable), "ERROR: TARGET UTILIZATION > CURRENT UTILIZATION"); uint targetSupply = borrowable.totalBorrows.mul(1e18).div(targetUtilizationRate); return targetSupply.sub(totalSupply(borrowable), "ERROR: TARGET SUPPLY > TOTAL SUPPLY"); } function compare(Borrowable memory borrowableA, Borrowable memory borrowableB) internal pure returns (bool) { return borrowableA.cachedSupplyRate > borrowableB.cachedSupplyRate; } }
pragma solidity =0.5.16; // a library for performing various math operations // forked from: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/libraries/Math.sol library Math { function min(uint x, uint y) internal pure returns (uint z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
pragma solidity =0.5.16; // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol // Subject to the MIT license. /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, errorMessage); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction underflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot underflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, errorMessage); return c; } /** * @dev Returns the integer division of two unsigned integers. * Reverts on division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. * Reverts with custom message on division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity =0.5.16; interface ERC20Interface { function balanceOf(address user) external view returns (uint256); } library SafeToken { function myBalance(address token) internal view returns (uint256) { return ERC20Interface(token).balanceOf(address(this)); } function balanceOf(address token, address user) internal view returns (uint256) { return ERC20Interface(token).balanceOf(user); } function safeApprove(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeApprove"); } function safeTransfer(address token, address to, uint256 value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransfer"); } function safeTransferFrom(address token, address from, address to, uint256 value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), "!safeTransferFrom"); } function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call.value(value)(new bytes(0)); require(success, "!safeTransferETH"); } }
pragma solidity =0.5.16; library StringHelpers { function append(string memory a, string memory b) internal pure returns (string memory) { return string(abi.encodePacked(a, b)); } /** * Returns the first string if it is not-empty, otherwise the second. */ function orElse(string memory a, string memory b) internal pure returns (string memory) { if (bytes(a).length > 0) { return a; } return b; } }
pragma solidity =0.5.16; import "./PoolToken.sol"; import "./LVStorageV1.sol"; import "./interfaces/ILendingVaultV1.sol"; import "./libraries/BorrowableHelpers.sol"; import "./libraries/BorrowableObject.sol"; contract LVAllocatorV1 is ILendingVaultV1, PoolToken, LVStorageV1 { using BorrowableHelpers for address; using BorrowableObject for BorrowableObject.Borrowable; function _allocate(IBorrowable borrowable, uint mintAmount, uint _exchangeRate) internal returns (uint mintTokens) { mintTokens = mintAmount.mul(1e18).div(_exchangeRate); if (mintTokens == 0) return 0; underlying.safeTransfer(address(borrowable), mintAmount); mintTokens = borrowable.mint(address(this)); emit AllocateIntoBorrowable(address(borrowable), mintAmount, mintTokens); } function _allocate(IBorrowable borrowable, uint mintAmount) internal returns (uint mintTokens) { mintTokens = _allocate(borrowable, mintAmount, borrowable.exchangeRate()); } function _deallocate(IBorrowable borrowable, uint redeemTokens, uint _exchangeRate) internal returns (uint redeemAmount) { redeemAmount = redeemTokens.mul(_exchangeRate).div(1e18); if (redeemAmount == 0) return 0; uint totalBalance = borrowable.totalBalance(); if (redeemAmount > totalBalance) { redeemTokens = totalBalance.mul(1e18).div(_exchangeRate); } address(borrowable).safeTransfer(address(borrowable), redeemTokens); redeemAmount = borrowable.redeem(address(this)); emit DeallocateFromBorrowable(address(borrowable), redeemAmount, redeemTokens); } function _deallocate(IBorrowable borrowable, uint redeemTokens) internal returns (uint redeemAmount) { redeemAmount = _deallocate(borrowable, redeemTokens, borrowable.exchangeRate()); } function _deallocateAtLeastOrMax(IBorrowable borrowable, uint redeemAmount, uint _exchangeRate) internal returns (uint actualRedeemAmount) { actualRedeemAmount = _deallocate(IBorrowable(borrowable), BorrowableHelpers.tokensForAtLeast(redeemAmount, _exchangeRate), _exchangeRate); } function _deallocateAtLeastOrMax(IBorrowable borrowable, uint redeemAmount) internal returns (uint actualRedeemAmount) { actualRedeemAmount = _deallocateAtLeastOrMax(borrowable, redeemAmount, borrowable.exchangeRate()); } function _withdrawAndReallocate(uint withdrawAmount) internal { // initialize borrowablesObj BorrowableObject.Borrowable[] memory borrowablesObj = new BorrowableObject.Borrowable[](borrowables.length); uint borrowablesLength = borrowables.length; for(uint i = 0; i < borrowables.length; i++) { if (!borrowableInfo[borrowables[i]].enabled) { borrowablesLength--; continue; } uint delta = uint(borrowables.length).sub(borrowablesLength); borrowablesObj[i - delta] = BorrowableObject.newBorrowable(IBorrowable(borrowables[i]), address(this)); } // deallocate everything uint amountToAllocate = underlying.myBalance(); for(uint i = 0; i < borrowablesLength; i++) { uint amount; (borrowablesObj[i], amount) = borrowablesObj[i].deallocateMax(); amountToAllocate = amountToAllocate.add(amount); } amountToAllocate = amountToAllocate.sub(withdrawAmount, "LendingVaultV1: INSUFFICIENT_LIQUIDITY"); // bubblesort borrowablesObj for (uint i = 0; i < borrowablesLength - 1; i++) { for (uint j = 0; j < borrowablesLength - 1 - i; j++) { if (!borrowablesObj[j].compare(borrowablesObj[j+1])) { BorrowableObject.Borrowable memory tmp = borrowablesObj[j]; borrowablesObj[j] = borrowablesObj[j+1]; borrowablesObj[j+1] = tmp; } } } // Allocate in the pool with the highest APR an amount such that the next APR matches the one // of the pool with the second highest APR. // Repeat until all the pools with the highest APR have the same APR. uint lastCycle = borrowablesLength; for(uint i = 1; i < borrowablesLength; i++) { uint targetRate = borrowablesObj[i].cachedSupplyRate; uint amountThisCycle = 0; uint[] memory amounts = new uint[](i); if (targetRate == 0) { // Unachievable APR lastCycle = i; break; } for (uint j = 0; j < i; j++) { if (borrowablesObj[j].cachedSupplyRate <= targetRate) break; amounts[j] = borrowablesObj[j].calculateAmountForRate(targetRate); amountThisCycle = amountThisCycle.add(amounts[j]); } if (amountThisCycle > amountToAllocate) { // We can't afford to complete this cycle lastCycle = i; break; } for (uint j = 0; j < i; j++) { if (amounts[j] == 0) continue; borrowablesObj[j] = borrowablesObj[j].allocate(amounts[j]); amountToAllocate = amountToAllocate.sub(amounts[j]); } } // distribute the amount left equally among pools with highest APR proportionally to their total supply uint globalTotalSupply = 0; uint totalAmountToAllocate = amountToAllocate; for (uint i = 0; i < lastCycle; i++) { globalTotalSupply = globalTotalSupply.add(borrowablesObj[i].totalSupply()); } for (uint i = 0; i < lastCycle; i++) { uint amount = globalTotalSupply > 0 ? borrowablesObj[i].totalSupply().mul(totalAmountToAllocate).div(globalTotalSupply) : amountToAllocate; if (amount > amountToAllocate) amount = amountToAllocate; borrowablesObj[i] = borrowablesObj[i].allocate(amount); amountToAllocate = amountToAllocate.sub(amount); } // redeem for(uint i = 0; i < borrowablesLength; i++) { if (borrowablesObj[i].ownedSupply < borrowablesObj[i].initialOwnedSupply) { uint redeemAmount = borrowablesObj[i].initialOwnedSupply.sub(borrowablesObj[i].ownedSupply); _deallocateAtLeastOrMax(borrowablesObj[i].borrowableContract, redeemAmount, borrowablesObj[i].exchangeRate); } } // mint amountToAllocate = underlying.myBalance().sub(withdrawAmount, "LendingVaultV1: NEGATIVE AMOUNT TO ALLOCATE"); for(uint i = 0; i < borrowablesLength; i++) { if (borrowablesObj[i].ownedSupply > borrowablesObj[i].initialOwnedSupply) { uint mintAmount = borrowablesObj[i].ownedSupply.sub(borrowablesObj[i].initialOwnedSupply); if (mintAmount > amountToAllocate) mintAmount = amountToAllocate; amountToAllocate = amountToAllocate.sub(mintAmount); _allocate(borrowablesObj[i].borrowableContract, mintAmount, borrowablesObj[i].exchangeRate); } } } }
pragma solidity =0.5.16; import "./LendingVaultV1.sol"; import "./interfaces/ILVDeployerV1.sol"; /* * This contract is used by the Factory to deploy LendingVaultV1 * The bytecode would be too long to fit in the Factory */ contract LVDeployerV1 is ILVDeployerV1 { constructor () public {} function deployVault() external returns (address vault) { vault = address(new LendingVaultV1()); } }
pragma solidity =0.5.16; import "./LVAllocatorV1.sol"; import "./interfaces/ILendingVaultV1Factory.sol"; contract LVSetterV1 is LVAllocatorV1 { uint public constant RESERVE_FACTOR_MAX = 0.90e18; //90% uint private constant MAX_BORROWABLES_LENGTH = 10; function _initialize( address _underlying, string calldata _name, string calldata _symbol ) external { require(msg.sender == factory, "LendingVaultV1: UNAUTHORIZED"); // sufficient check _setName(_name, _symbol); underlying = _underlying; exchangeRateLast = initialExchangeRate; } function _setReserveFactor(uint newReserveFactor) external onlyAdmin nonReentrant { require(newReserveFactor <= RESERVE_FACTOR_MAX, "LendingVaultV1: INVALID_SETTING"); reserveFactor = newReserveFactor; emit NewReserveFactor(newReserveFactor); } /*** Borrowables management ***/ function addBorrowable(address borrowable) external onlyAdmin nonReentrant { require(IBorrowable(borrowable).underlying() == underlying, "LendingVaultV1: INVALID_UNDERLYING"); require(!borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_EXISTS"); require(borrowables.length < MAX_BORROWABLES_LENGTH, "LendingVaultV1: MAX_BORROWABLES_LENGTH"); borrowableInfo[borrowable].exists = true; borrowableInfo[borrowable].enabled = true; borrowables.push(borrowable); emit AddBorrowable(address(borrowable)); } function removeBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); require(borrowable.balanceOf(address(this)) == 0, "LendingVaultV1: NOT_EMPTY"); uint lastIndex = borrowables.length - 1; uint index = indexOfBorrowable(borrowable); borrowables[index] = borrowables[lastIndex]; borrowables.pop(); delete borrowableInfo[borrowable]; emit RemoveBorrowable(address(borrowable)); } function disableBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_DISABLED"); borrowableInfo[borrowable].enabled = false; emit DisableBorrowable(address(borrowable)); } function enableBorrowable(address borrowable) external onlyAdmin nonReentrant { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); borrowableInfo[borrowable].enabled = true; emit EnableBorrowable(address(borrowable)); } function unwindBorrowable(address borrowable) external onlyAdmin nonReentrant update { require(borrowableInfo[borrowable].exists, "LendingVaultV1: BORROWABLE_DOESNT_EXISTS"); require(!borrowableInfo[borrowable].enabled, "LendingVaultV1: BORROWABLE_ENABLED"); uint underlyingBalance = borrowable.myUnderlyingBalance(); require(underlyingBalance > 0, "LendingVaultV1: ZERO_AMOUNT"); uint actualRedeemAmount = _deallocateAtLeastOrMax(IBorrowable(borrowable), underlyingBalance); emit UnwindBorrowable(address(borrowable), underlyingBalance, actualRedeemAmount); } modifier onlyAdmin() { require(msg.sender == ILendingVaultV1Factory(factory).admin(), "LendingVaultV1: UNAUTHORIZED"); _; } }
pragma solidity =0.5.16; contract LVStorageV1 { address[] public borrowables; struct BorrowableInfo { bool enabled; bool exists; } mapping(address => BorrowableInfo) public borrowableInfo; function getBorrowablesLength() external view returns (uint) { return borrowables.length; } function indexOfBorrowable(address borrowable) public view returns (uint) { for (uint i = 0; i < borrowables.length; i++) { if (borrowables[i] == borrowable) { return i; } } require(false, "LendingVaultV1: BORROWABLE_NOT_FOUND"); } uint public exchangeRateLast; uint public reserveFactor = 0.10e18; //10% }
pragma solidity =0.5.16; import "./ImpermaxERC20.sol"; import "./interfaces/IPoolToken.sol"; import "./libraries/SafeToken.sol"; contract PoolToken is IPoolToken, ImpermaxERC20 { using SafeToken for address; uint internal constant initialExchangeRate = 1e18; address public underlying; address public factory; uint public totalBalance; uint public constant MINIMUM_LIQUIDITY = 1000; event Mint(address indexed sender, address indexed minter, uint mintAmount, uint mintTokens); event Redeem(address indexed sender, address indexed redeemer, uint redeemAmount, uint redeemTokens); event Sync(uint totalBalance); /*** Initialize ***/ // called once by the factory function _setFactory() external { require(factory == address(0), "Impermax: FACTORY_ALREADY_SET"); factory = msg.sender; } /*** PoolToken ***/ function _update() internal { totalBalance = underlying.myBalance(); emit Sync(totalBalance); } function exchangeRate() public returns (uint) { uint _totalSupply = totalSupply; // gas savings uint _totalBalance = totalBalance; // gas savings if (_totalSupply == 0 || _totalBalance == 0) return initialExchangeRate; return _totalBalance.mul(1e18).div(_totalSupply); } // this low-level function should be called from another contract function mint(address minter) external nonReentrant update returns (uint mintTokens) { uint balance = underlying.myBalance(); uint mintAmount = balance.sub(totalBalance); mintTokens = mintAmount.mul(1e18).div(exchangeRate()); if(totalSupply == 0) { // permanently lock the first MINIMUM_LIQUIDITY tokens mintTokens = mintTokens.sub(MINIMUM_LIQUIDITY); _mint(address(0), MINIMUM_LIQUIDITY); } require(mintTokens > 0, "Impermax: MINT_AMOUNT_ZERO"); _mint(minter, mintTokens); emit Mint(msg.sender, minter, mintAmount, mintTokens); } // this low-level function should be called from another contract function redeem(address redeemer) external nonReentrant update returns (uint redeemAmount) { uint redeemTokens = balanceOf[address(this)]; redeemAmount = redeemTokens.mul(exchangeRate()).div(1e18); require(redeemAmount > 0, "Impermax: REDEEM_AMOUNT_ZERO"); require(redeemAmount <= totalBalance, "Impermax: INSUFFICIENT_CASH"); _burn(address(this), redeemTokens); underlying.safeTransfer(redeemer, redeemAmount); emit Redeem(msg.sender, redeemer, redeemAmount, redeemTokens); } // force real balance to match totalBalance function skim(address to) external nonReentrant { underlying.safeTransfer(to, underlying.myBalance().sub(totalBalance)); } // force totalBalance to match real balance function sync() external nonReentrant update {} /*** Utilities ***/ // prevents a contract from calling itself, directly or indirectly. bool internal _notEntered = true; modifier nonReentrant() { require(_notEntered, "Impermax: REENTERED"); _notEntered = false; _; _notEntered = true; } // update totalBalance with current balance modifier update() { _; _update(); } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_reservesAdmin","type":"address"},{"internalType":"contract ILVDeployerV1","name":"_LVDeployerV1","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"NewPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldReservesAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newReservesAdmin","type":"address"}],"name":"NewReservesAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldReservesManager","type":"address"},{"indexed":false,"internalType":"address","name":"newReservesManager","type":"address"}],"name":"NewReservesManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldReservesPendingAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newReservesPendingAdmin","type":"address"}],"name":"NewReservesPendingAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"VaultCreated","type":"event"},{"constant":true,"inputs":[],"name":"LVDeployerV1","outputs":[{"internalType":"contract ILVDeployerV1","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"_acceptAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"_acceptReservesAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newPendingAdmin","type":"address"}],"name":"_setPendingAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newReservesManager","type":"address"}],"name":"_setReservesManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newReservesPendingAdmin","type":"address"}],"name":"_setReservesPendingAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allVaults","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"allVaultsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"underlying","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"createVault","outputs":[{"internalType":"address","name":"vault","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"pendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reservesAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reservesManager","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"reservesPendingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506040516113563803806113568339818101604052606081101561003357600080fd5b508051602080830151604093840151600080546001600160a01b03199081166001600160a01b038088169182178455600280548416828816179055600680549093169085161790915586519182529381019390935284519394919390927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a160408051600081526001600160a01b038416602082015281517fa328ba21363a99cbf330243928bb26a15acf20bf43166ef838e67ff5d84d4ae7929181900390910190a15050506112478061010f6000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063998c077d1161008c578063b71d1a0c11610066578063b71d1a0c14610293578063e9c714f2146102c6578063eb5ab75f146102ce578063f851a44014610301576100ea565b8063998c077d1461024e5780639e1348e314610258578063b1ccc03e14610260576100ea565b80634cd18577116100c85780634cd1857714610130578063515d61ec1461014a578063822d73b2146102295780639094a91e14610231576100ea565b80630778b501146100ef5780632678224714610120578063345ef94114610128575b600080fd5b6100f7610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100f7610325565b6100f7610341565b61013861035d565b60408051918252519081900360200190f35b6100f76004803603606081101561016057600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561019857600080fd5b8201836020820111156101aa57600080fd5b803590602001918460018302840111640100000000831117156101cc57600080fd5b9193909290916020810190356401000000008111156101ea57600080fd5b8201836020820111156101fc57600080fd5b8035906020019184600183028401116401000000008311171561021e57600080fd5b509092509050610363565b6100f7610aa3565b6100f76004803603602081101561024757600080fd5b5035610abf565b610256610af3565b005b6100f7610c48565b6102566004803603602081101561027657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c64565b610256600480360360208110156102a957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610d5c565b610256610e54565b610256600480360360208110156102e457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610fa9565b6100f76110a1565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60055490565b6000606061058461053f6040518060400160405280600e81526020017f204c656e64696e67205661756c740000000000000000000000000000000000008152506105338a73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156103ec57600080fd5b505afa158015610400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561044757600080fd5b810190808051604051939291908464010000000082111561046757600080fd5b90830190602082018581111561047c57600080fd5b825164010000000081118282018810171561049657600080fd5b82525081516020918201929091019080838360005b838110156104c35781810151838201526020016104ab565b50505050905090810190601f1680156104f05780820380516001836020036101000a031916815260200191505b5060408181019052600981527f496d7065726d617820000000000000000000000000000000000000000000000060208201529392505063ffffffff6110bd169050565b9063ffffffff6110bd16565b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505063ffffffff6111d3169050565b9050606061076061071b8973ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156105d457600080fd5b505afa1580156105e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561062f57600080fd5b810190808051604051939291908464010000000082111561064f57600080fd5b90830190602082018581111561066457600080fd5b825164010000000081118282018810171561067e57600080fd5b82525081516020918201929091019080838360005b838110156106ab578181015183820152602001610693565b50505050905090810190601f1680156106d85780820380516001836020036101000a031916815260200191505b5060408181019052600181527f690000000000000000000000000000000000000000000000000000000000000060208201529392505063ffffffff6110bd169050565b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505063ffffffff6111d3169050565b9050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663901c4e4f6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b505050506040513d60208110156107f657600080fd5b5051604080517f4a5d316c000000000000000000000000000000000000000000000000000000008152905191945073ffffffffffffffffffffffffffffffffffffffff851691634a5d316c9160048082019260009290919082900301818387803b15801561086357600080fd5b505af1158015610877573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff16634643ec588984846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561091c578181015183820152602001610904565b50505050905090810190601f1680156109495780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561097c578181015183820152602001610964565b50505050905090810190601f1680156109a95780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b50506005805460018101825560008290527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88811691821790925591546040805193845260208401919091528051918d1694507f0b045af6aff86dd2cda5342fd0329a354dc66759ff1eda00d7ecf13a76c7fb3b93509181900390910190a2505095945050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60058181548110610acc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035473ffffffffffffffffffffffffffffffffffffffff163314610b63576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b600280546003805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179687905590921690925560408051938316808552949092166020840152815190927fa328ba21363a99cbf330243928bb26a15acf20bf43166ef838e67ff5d84d4ae792908290030190a16040805173ffffffffffffffffffffffffffffffffffffffff831681526000602082015281517f01d5e27ed5584d16c62ba1a14cfde0783f979d4797a3fc41342aff17d8ef5b41929181900390910190a15050565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff163314610cd4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6003805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517f01d5e27ed5584d16c62ba1a14cfde0783f979d4797a3fc41342aff17d8ef5b41929181900390910190a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dcc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a15050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ec4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b600080546001805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179687905590921690925560408051938316808552949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a16040805173ffffffffffffffffffffffffffffffffffffffff831681526000602082015281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a15050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611019576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517f324bacfad26225895fcf55780481bec4ce49013c92500fa1c25626ff43fbf661929181900390910190a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b606082826040516020018083805190602001908083835b6020831061111157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016110d4565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b6020831061119557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611158565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405290505b92915050565b8151606090156111e45750816111cd565b5091905056fe4c656e64696e6741676772656761746f725631466163746f72793a20554e415554484f52495a4544a265627a7a72315820f02d1da2f122c078300064d4db3edc3568c2fbb73ca82fef6a77177910ec50bf64736f6c634300051000320000000000000000000000007226c7ca07056c655865216e04512e9b287829590000000000000000000000009fd93712400902bff6040efa72b28bf80152f056000000000000000000000000a403128dd76566a6fc1c3328d204ad6ef38a24d0
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063998c077d1161008c578063b71d1a0c11610066578063b71d1a0c14610293578063e9c714f2146102c6578063eb5ab75f146102ce578063f851a44014610301576100ea565b8063998c077d1461024e5780639e1348e314610258578063b1ccc03e14610260576100ea565b80634cd18577116100c85780634cd1857714610130578063515d61ec1461014a578063822d73b2146102295780639094a91e14610231576100ea565b80630778b501146100ef5780632678224714610120578063345ef94114610128575b600080fd5b6100f7610309565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6100f7610325565b6100f7610341565b61013861035d565b60408051918252519081900360200190f35b6100f76004803603606081101561016057600080fd5b73ffffffffffffffffffffffffffffffffffffffff823516919081019060408101602082013564010000000081111561019857600080fd5b8201836020820111156101aa57600080fd5b803590602001918460018302840111640100000000831117156101cc57600080fd5b9193909290916020810190356401000000008111156101ea57600080fd5b8201836020820111156101fc57600080fd5b8035906020019184600183028401116401000000008311171561021e57600080fd5b509092509050610363565b6100f7610aa3565b6100f76004803603602081101561024757600080fd5b5035610abf565b610256610af3565b005b6100f7610c48565b6102566004803603602081101561027657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610c64565b610256600480360360208110156102a957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610d5c565b610256610e54565b610256600480360360208110156102e457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610fa9565b6100f76110a1565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60045473ffffffffffffffffffffffffffffffffffffffff1681565b60055490565b6000606061058461053f6040518060400160405280600e81526020017f204c656e64696e67205661756c740000000000000000000000000000000000008152506105338a73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156103ec57600080fd5b505afa158015610400573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561044757600080fd5b810190808051604051939291908464010000000082111561046757600080fd5b90830190602082018581111561047c57600080fd5b825164010000000081118282018810171561049657600080fd5b82525081516020918201929091019080838360005b838110156104c35781810151838201526020016104ab565b50505050905090810190601f1680156104f05780820380516001836020036101000a031916815260200191505b5060408181019052600981527f496d7065726d617820000000000000000000000000000000000000000000000060208201529392505063ffffffff6110bd169050565b9063ffffffff6110bd16565b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505063ffffffff6111d3169050565b9050606061076061071b8973ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156105d457600080fd5b505afa1580156105e8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561062f57600080fd5b810190808051604051939291908464010000000082111561064f57600080fd5b90830190602082018581111561066457600080fd5b825164010000000081118282018810171561067e57600080fd5b82525081516020918201929091019080838360005b838110156106ab578181015183820152602001610693565b50505050905090810190601f1680156106d85780820380516001836020036101000a031916815260200191505b5060408181019052600181527f690000000000000000000000000000000000000000000000000000000000000060208201529392505063ffffffff6110bd169050565b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929392505063ffffffff6111d3169050565b9050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663901c4e4f6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107cc57600080fd5b505af11580156107e0573d6000803e3d6000fd5b505050506040513d60208110156107f657600080fd5b5051604080517f4a5d316c000000000000000000000000000000000000000000000000000000008152905191945073ffffffffffffffffffffffffffffffffffffffff851691634a5d316c9160048082019260009290919082900301818387803b15801561086357600080fd5b505af1158015610877573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff16634643ec588984846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561091c578181015183820152602001610904565b50505050905090810190601f1680156109495780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561097c578181015183820152602001610964565b50505050905090810190601f1680156109a95780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156109cb57600080fd5b505af11580156109df573d6000803e3d6000fd5b50506005805460018101825560008290527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88811691821790925591546040805193845260208401919091528051918d1694507f0b045af6aff86dd2cda5342fd0329a354dc66759ff1eda00d7ecf13a76c7fb3b93509181900390910190a2505095945050505050565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60058181548110610acc57fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b60035473ffffffffffffffffffffffffffffffffffffffff163314610b63576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b600280546003805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179687905590921690925560408051938316808552949092166020840152815190927fa328ba21363a99cbf330243928bb26a15acf20bf43166ef838e67ff5d84d4ae792908290030190a16040805173ffffffffffffffffffffffffffffffffffffffff831681526000602082015281517f01d5e27ed5584d16c62ba1a14cfde0783f979d4797a3fc41342aff17d8ef5b41929181900390910190a15050565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b60025473ffffffffffffffffffffffffffffffffffffffff163314610cd4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6003805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517f01d5e27ed5584d16c62ba1a14cfde0783f979d4797a3fc41342aff17d8ef5b41929181900390910190a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dcc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a15050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ec4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b600080546001805473ffffffffffffffffffffffffffffffffffffffff8082167fffffffffffffffffffffffff000000000000000000000000000000000000000080861682179687905590921690925560408051938316808552949092166020840152815190927ff9ffabca9c8276e99321725bcb43fb076a6c66a54b7f21c4e8146d8519b417dc92908290030190a16040805173ffffffffffffffffffffffffffffffffffffffff831681526000602082015281517fca4f2f25d0898edd99413412fb94012f9e54ec8142f9b093e7720646a95b16a9929181900390910190a15050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611019576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806111eb6028913960400191505060405180910390fd5b6004805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040805191909216808252602082019390935281517f324bacfad26225895fcf55780481bec4ce49013c92500fa1c25626ff43fbf661929181900390910190a15050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b606082826040516020018083805190602001908083835b6020831061111157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016110d4565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b6020831061119557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611158565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405290505b92915050565b8151606090156111e45750816111cd565b5091905056fe4c656e64696e6741676772656761746f725631466163746f72793a20554e415554484f52495a4544a265627a7a72315820f02d1da2f122c078300064d4db3edc3568c2fbb73ca82fef6a77177910ec50bf64736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007226c7ca07056c655865216e04512e9b287829590000000000000000000000009fd93712400902bff6040efa72b28bf80152f056000000000000000000000000a403128dd76566a6fc1c3328d204ad6ef38a24d0
-----Decoded View---------------
Arg [0] : _admin (address): 0x7226C7ca07056c655865216E04512E9B28782959
Arg [1] : _reservesAdmin (address): 0x9fd93712400902bff6040efa72B28Bf80152F056
Arg [2] : _LVDeployerV1 (address): 0xa403128Dd76566a6fC1C3328d204ad6ef38A24D0
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000007226c7ca07056c655865216e04512e9b28782959
Arg [1] : 0000000000000000000000009fd93712400902bff6040efa72b28bf80152f056
Arg [2] : 000000000000000000000000a403128dd76566a6fc1c3328d204ad6ef38a24d0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.