Contract Overview
Balance:
0 MATIC
My Name Tag:
Not Available
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x26fcf601766331d37fcd202edddd5d9d150aaafc425cffddefb1e5ae30cab722 | Create Pool | 18698086 | 639 days 19 hrs ago | 0xfd9656df3e4dca84c260137aecba416050aea145 | IN | 0x0b272a52e64542c7b2bfe001ffe6ead1ae24c4b8 | 0 MATIC | 0.017262714 | |
0xb77afe0df2c6295e561d92cefd83101b0c6c79a8ad2d1ea65bf6433dec223318 | Create Pool | 18698085 | 639 days 19 hrs ago | 0xfd9656df3e4dca84c260137aecba416050aea145 | IN | 0x0b272a52e64542c7b2bfe001ffe6ead1ae24c4b8 | 0 MATIC | 0.017262822 | |
0xf600c8bc7fca3bf9dc75f81e01cd94da84fea47460235279c1208ce744222880 | Create Pool | 18698084 | 639 days 19 hrs ago | 0xfd9656df3e4dca84c260137aecba416050aea145 | IN | 0x0b272a52e64542c7b2bfe001ffe6ead1ae24c4b8 | 0 MATIC | 0.017314122 | |
0xdc36b260c62362f41f1fc88a7ece3736e931a537bb7fe406aa69d85a4dadb685 | 0x60806040 | 18698081 | 639 days 19 hrs ago | 0xfd9656df3e4dca84c260137aecba416050aea145 | IN | Create: LosslessV2Factory | 0 MATIC | 0.016083093 |
[ Download CSV Export ]
Latest 12 internal transactions
[ Download CSV Export ]
Contract Name:
LosslessV2Factory
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "./LosslessV2Token.sol"; import "./LosslessV2Pool.sol"; import "../interfaces/ILosslessV2Factory.sol"; import "./ERC20.sol"; contract LosslessV2Factory is ILosslessV2Factory { address public override feeTo; address public override DAO; address public override pendingDAO; uint256 public override feePercent; // usage: fee = totalInterest.mul(feePercent).div(PRECISION) // all pool related address[] public override allPools; // BTC - USDT: USDT, DAI, USDC // bidToken ----> principalToken -> poolAddress // | | | mapping(address => mapping(address => address)) public override getPool; mapping(address => bool) public override isPoolActive; mapping(address => address) public override getPoolShortToken; mapping(address => address) public override getPoolLongToken; mapping(address => address) public override getPoolSponsorToken; modifier onlyDAO() { require(msg.sender == DAO, "LosslessV2Factory: FORBIDDEN"); _; } constructor(address _DAO) public { require(_DAO != address(0), "LosslessV2Factory: set DAO the zero address"); DAO = _DAO; // default is DAO } function allPoolsLength() external view override returns (uint256) { return allPools.length; } function createPool( address bidToken, address principalToken, address addressProvider, address aggregator, uint256 biddingDuration, uint256 gamingDuration, string memory tokenName, string memory tokenSymbol ) external override onlyDAO { // pool setting check require(bidToken != principalToken, "LosslessV2Factory: IDENTICAL_ADDRESSES"); require((bidToken != address(0)) && (principalToken != address(0)), "LosslessV2Factory: ZERO_ADDRESS"); require(addressProvider != address(0), "LosslessV2Factory: ADDRESS PROVIDER ZERO_ADDRESS"); require(aggregator != address(0), "LosslessV2Factory: AGGREGATOR ZERO_ADDRESS"); require(getPool[bidToken][principalToken] == address(0), "LosslessV2Factory: POOL_EXISTS"); require(biddingDuration > 0, "LosslessV2Factory: BIDDING DURATION INVALID_AMOUNT"); require(gamingDuration > 0, "LosslessV2Factory: GAMING DURATION INVALID_AMOUNT"); // token name and symbol check require(bytes(tokenName).length != 0, "LosslessV2Factory: TOKEN NAME INPUT IS INVALID"); require(bytes(tokenSymbol).length != 0, "LosslessV2Factory: TOKEN SYMBOL INPUT IS INVALID"); bytes32 salt = keccak256(abi.encodePacked(allPools.length, bidToken, principalToken, addressProvider, aggregator)); LosslessV2Pool newPool = new LosslessV2Pool{ salt: salt }(bidToken, principalToken, addressProvider, aggregator, biddingDuration, gamingDuration); (address shortToken, address longToken, address sponsorToken) = _initializeTokens( tokenName, tokenSymbol, ERC20(principalToken).decimals(), address(newPool) ); newPool.initialize(shortToken, longToken, sponsorToken); // save pool address to pool related getPool[bidToken][principalToken] = address(newPool); allPools.push(address(newPool)); isPoolActive[address(newPool)] = true; // save pool tokens related getPoolShortToken[address(newPool)] = shortToken; getPoolLongToken[address(newPool)] = longToken; getPoolSponsorToken[address(newPool)] = sponsorToken; emit PoolCreated(bidToken, principalToken, address(newPool), allPools.length); } ///@dev only DAO can call this function function terminatePool(address pool) external onlyDAO returns (bool) { require(isPoolActive[pool] == true, "LosslessV2Factory: POOL MUST BE ACTIVE"); // call pool termination function to LosslessV2Pool(pool).poolTermination(); // update pool related isPoolActive[pool] = false; emit PoolTerminated(pool); return true; } function _initializeTokens( string memory _tokenName, string memory _tokenSymbol, uint8 _decimals, address _pool ) private returns ( address shortToken, address longToken, address sponsorToken ) { require(_pool != address(0), "LosslessV2Factory: ADDRESS PROVIDER ZERO_ADDRESS"); // create a list of tokens for the new pool shortToken = _createToken(string(abi.encodePacked("st", _tokenName)), string(abi.encodePacked("st", _tokenSymbol)), _decimals, _pool); longToken = _createToken(string(abi.encodePacked("lg", _tokenName)), string(abi.encodePacked("lg", _tokenSymbol)), _decimals, _pool); sponsorToken = _createToken(string(abi.encodePacked("sp", _tokenName)), string(abi.encodePacked("sp", _tokenSymbol)), _decimals, _pool); } function _createToken( string memory _name, string memory _symbol, uint8 _decimals, address _pool ) private returns (address) { bytes32 salt = keccak256(abi.encodePacked(_name, _symbol, _decimals, _pool)); LosslessV2Token newToken = new LosslessV2Token{ salt: salt }(_name, _symbol, _decimals, _pool); return address(newToken); } // below functions all limited to DAO /** * @dev The default DAO can assign the receiver of the trading fee * @param _feeTo the receiver of the trading fee **/ function setFeeTo(address _feeTo) external override onlyDAO { require(_feeTo != address(0), "LosslessV2Factory: set feeTo to the zero address"); feeTo = _feeTo; emit FeeToChanged(feeTo); } /** * @dev only DAO can set the feePercent (usage: fee = totalInterest.mul(feePercent).div(PRECISION)) * @param _feePercent percentage of total interest as trading fee: 1% - 100, 10% - 1000, 100% - 10000 **/ function setFeePercent(uint256 _feePercent) external override onlyDAO { require(_feePercent < 10**4, "LosslessV2Factory: feePercent must be less than PRECISION"); feePercent = _feePercent; emit FeePercentChanged(feePercent); } /** * @dev The default DAO and DAO can assign pendingDAO to others by calling `setDAO` * @param _pendingDAO new DAO address **/ function setPendingDAO(address _pendingDAO) external override onlyDAO { require(_pendingDAO != address(0), "LosslessV2Factory: set _pendingDAO to the zero address"); pendingDAO = _pendingDAO; emit proposeDAOChange(pendingDAO); } /** * @dev double confirm on whether to accept the pending changes or not **/ function setDAO() external override onlyDAO { require(pendingDAO != address(0), "LosslessV2Factory: set _DAO to the zero address"); DAO = pendingDAO; pendingDAO = address(0); emit DAOChanged(DAO); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "./ERC20.sol"; import "../interfaces/ILosslessV2Pool.sol"; contract LosslessV2Token is ERC20 { address public adminPool; // limit only pool can mint token modifier onlyAdminPool() { require(msg.sender == adminPool, "LosslessV2Token: FORBIDDEN"); _; } constructor( string memory _name, string memory _symbol, uint8 _decimals, address _adminPool ) public ERC20(_name, _symbol, _decimals) { require(address(0) != _adminPool, "LosslessV2Token: set pool to the zero address"); adminPool = _adminPool; } function mint(address _to, uint256 _amount) external onlyAdminPool returns (bool) { _mint(_to, _amount); return true; } function burn(address _from, uint256 _amount) external onlyAdminPool returns (bool) { _burn(_from, _amount); return true; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "../interfaces/ILosslessV2Pool.sol"; import "../interfaces/ILosslessV2Factory.sol"; import "../interfaces/ILosslessV2Token.sol"; import "../interfaces/IPriceOracleGetter.sol"; import "../interfaces/ILendingPoolAddressesProvider.sol"; import "../interfaces/ILendingPool.sol"; import "../interfaces/IProtocolDataProvider.sol"; import "../interfaces/IStakedToken.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol"; import "@chainlink/contracts/src/v0.6/interfaces/KeeperCompatibleInterface.sol"; contract LosslessV2Pool is ILosslessV2Pool, KeeperCompatibleInterface{ using SafeMath for uint256; // basic info for initializing a pool address public override factory; address public override bidToken; address public override principalToken; address public override aToken; address public override addressProvider; AggregatorV3Interface private priceFeed; // used for calculating share price, define the precision is 0.0001 uint256 public constant PRECISION = 10**4; ///@dev the actual share value is valuePerShortToken / PRECISION (constant = 10000) uint256 public valuePerShortToken = PRECISION; // the value of a single share - short uint256 public valuePerLongToken = PRECISION; // the value of a single share - long uint256 public constant valuePerSponsorToken = PRECISION; // the value of sponsor share should be fixed to PRECISION uint256 private totalInterest; GameStatus public status; PoolTokensInfo public poolTokensInfo; mapping(address => uint256) public override inPoolTimestamp; ILosslessV2Token private _shortToken; ILosslessV2Token private _longToken; ILosslessV2Token private _sponsorToken; // lock modifier bool private accepting = true; modifier lock() { require(accepting == true, "LosslessV2Pool: LOCKED"); accepting = false; _; accepting = true; } modifier onlyFactory() { require(msg.sender == factory, "LosslessV2Factory: FACTORY ONLY"); _; } modifier onlyAfter(uint256 _time) { require(block.timestamp > _time, "LosslessV2Pool: INVALID TIMESTAMP AFTER"); _; } constructor( address _bidToken, address _principalToken, address _addressProvider, address _aggregator, uint256 _biddingDuration, uint256 _gamingDuration ) public { factory = msg.sender; bidToken = _bidToken; principalToken = _principalToken; addressProvider = _addressProvider; aToken = _getATokenAddress(principalToken); priceFeed = AggregatorV3Interface(_aggregator); // modify status variable status.gameRound = 1; status.durationOfBidding = _biddingDuration; status.durationOfGame = _gamingDuration; status.lastUpdateTimestamp = block.timestamp; // status.initialPrice - unchange for now // status.endPrice - unchange for now // status.isShortLastRoundWinner - default to false status.isFirstRound = true; status.isFirstUser = true; status.currState = PoolStatus.FirstGame; } /** * @dev initialize pool **/ function initialize( address shortToken_, address longToken_, address sponsorToken_ ) external override onlyFactory { poolTokensInfo.shortToken = shortToken_; poolTokensInfo.longToken = longToken_; poolTokensInfo.sponsorToken = sponsorToken_; _shortToken = ILosslessV2Token(shortToken_); _longToken = ILosslessV2Token(longToken_); _sponsorToken = ILosslessV2Token(sponsorToken_); } /** * @dev only be called once, after initalize **/ function startFirstRound() external override { require(status.isFirstRound == true, "LosslessV2Pool: NOT FIRST ROUND!"); require(status.currState == PoolStatus.FirstGame, "LosslessV2Pool: WRONG STATUS"); // modify status variable // status.gameRound = 1; status.lastUpdateTimestamp = block.timestamp; // status.initialPrice - unchange for now // status.endPrice - unchange for now // status.isShortLastRoundWinner - unchange for now status.isFirstRound = false; // status.isFirstUser = true; status.currState = PoolStatus.Accepting; } /** * @dev start the gaming, lock pool and transfer asset to defi lending **/ function startGame() public override lock onlyAfter(status.lastUpdateTimestamp.add(status.durationOfBidding)) { require(status.currState == PoolStatus.Accepting, "LosslessV2Pool: WRONG STATUS"); require(_shortToken.totalSupply() != 0 && _longToken.totalSupply() != 0, "LosslessV2Pool: NO FUND IN POOL"); // modify status variable // status.gameRound = 1; status.lastUpdateTimestamp = block.timestamp; // fisrt user can set the inital price if (status.isFirstUser == true) { status.initialPrice = _getPrice(); status.isFirstUser = false; } // status.endPrice - unchange for now // status.isShortLastRoundWinner - unchange for now // status.isFirstRound = false; // status.isFirstUser = true; status.currState = PoolStatus.Locked; // transfer to aave _supplyToAAVE(principalToken, IERC20(principalToken).balanceOf(address(this))); } /** * @dev end the gaming, redeem assets from aave and get end price **/ function endGame() public override lock onlyAfter(status.lastUpdateTimestamp.add(status.durationOfGame)) { require(status.currState == PoolStatus.Locked, "LosslessV2Pool: WRONG STATUS"); // modify status variable status.gameRound = status.gameRound.add(1); status.lastUpdateTimestamp = block.timestamp; // status.initialPrice - unchange for now // status.endPrice - unchange for now // status.isShortLastRoundWinner - unchange for now // status.isFirstRound = false; status.isFirstUser = true; status.currState = PoolStatus.Accepting; // redeem from AAVE _redeemFromAAVE(principalToken, 0); // redeem all // get end price status.endPrice = _getPrice(); // if end price higher than inital price -> long users win ! if (status.endPrice >= status.initialPrice) { status.isShortLastRoundWinner = false; } else { status.isShortLastRoundWinner = true; } // update interest and principal amount uint256 totalShortPrincipal = _shortToken.totalSupply().mul(valuePerShortToken).div(PRECISION); uint256 totalLongPrincipal = _longToken.totalSupply().mul(valuePerLongToken).div(PRECISION); uint256 totalSponsorPrincipal = _sponsorToken.totalSupply().mul(valuePerSponsorToken).div(PRECISION); uint256 totalPrincipal = totalShortPrincipal.add(totalLongPrincipal.add(totalSponsorPrincipal)); if (IERC20(principalToken).balanceOf(address(this)) < totalPrincipal) { totalInterest = 0; // in case kovan testnet give us aToken slightly less than deposit amount } else { totalInterest = IERC20(principalToken).balanceOf(address(this)).sub(totalPrincipal); } // update share value _updateTokenValue(totalShortPrincipal, totalLongPrincipal); emit AnnounceWinner(status.isShortLastRoundWinner, status.initialPrice, status.endPrice); } /** * @dev chainlink keeper checkUpkeep function to constantly check whether we need function call **/ function checkUpkeep(bytes calldata checkData) external override returns (bool upkeepNeeded, bytes memory performData) { PoolStatus currState = status.currState; uint256 lastUpdateTimestamp = status.lastUpdateTimestamp; uint256 durationOfGame = status.durationOfGame; uint256 durationOfBidding = status.durationOfBidding; if (currState == PoolStatus.Accepting && block.timestamp > lastUpdateTimestamp.add(durationOfBidding)) { upkeepNeeded = true; } else if (currState == PoolStatus.Locked && block.timestamp > lastUpdateTimestamp.add(durationOfGame)) { upkeepNeeded = true; } else { upkeepNeeded = false; } performData = checkData; } /** * @dev once checkUpKeep been trigered, keeper will call performUpKeep **/ function performUpkeep(bytes calldata performData) external override { PoolStatus currState = status.currState; uint256 lastUpdateTimestamp = status.lastUpdateTimestamp; uint256 durationOfGame = status.durationOfGame; uint256 durationOfBidding = status.durationOfBidding; if (currState == PoolStatus.Accepting && block.timestamp > lastUpdateTimestamp.add(durationOfBidding)) { startGame(); } if (currState == PoolStatus.Locked && block.timestamp > lastUpdateTimestamp.add(durationOfGame)) { endGame(); } performData; } /** * @dev termination function, use this to terminate the game **/ function poolTermination() external override onlyFactory { // only when pool status is at Accepting require(status.currState == PoolStatus.Accepting, "LosslessV2Pool: WRONG STATUS"); // modify status variable // status.gameRound = status.gameRound.add(1); // status.durationOfGame = 6 days; // status.durationOfBidding = 1 days; // status.lastUpdateTimestamp = block.timestamp; // status.initialPrice - unchange for now // status.endPrice - unchange for now // status.isShortLastRoundWinner - unchange for now // status.isFirstRound = false; // status.isFirstUser = true; status.currState = PoolStatus.Terminated; } /** * @dev users can add principal as long as the status is accpeting * @param shortPrincipalAmount how many principal in short pool does user want to deposit * @param longPrincipalAmount how many principal in long pool does user want to deposit **/ function deposit(uint256 shortPrincipalAmount, uint256 longPrincipalAmount) external override lock { require(status.currState == PoolStatus.Accepting, "LosslessV2Pool: WRONG STATUS"); require(shortPrincipalAmount > 0 || longPrincipalAmount > 0, "LosslessV2Pool: INVALID AMOUNT"); // fisrt user can set the inital price if (status.isFirstUser == true) { status.initialPrice = _getPrice(); status.isFirstUser = false; } // // if user's balance is zero record user's join timestamp for reward if (_shortToken.balanceOf(msg.sender) == 0 && _longToken.balanceOf(msg.sender) == 0) { inPoolTimestamp[msg.sender] = block.timestamp; } // transfer principal to pool contract SafeERC20.safeTransferFrom(IERC20(principalToken), msg.sender, address(this), shortPrincipalAmount.add(longPrincipalAmount)); _mintTokens(true, msg.sender, shortPrincipalAmount, longPrincipalAmount); emit Deposit(shortPrincipalAmount, longPrincipalAmount); } /** * @dev user can call it to redeem pool tokens to principal tokens * @param shortTokenAmount how many short token in short pool does user want to redeem * @param longTokenAmount how many long token in long pool does user want to redeem **/ function withdraw( bool isAToken, uint256 shortTokenAmount, uint256 longTokenAmount ) external override lock { // withdraw should have no limitation in pool status require(shortTokenAmount > 0 || longTokenAmount > 0, "LosslessV2Pool: INVALID AMOUNT"); // check user token balance uint256 userShortTokenBalance = _shortToken.balanceOf(msg.sender); uint256 userLongTokenBalance = _longToken.balanceOf(msg.sender); require(userShortTokenBalance >= shortTokenAmount && userLongTokenBalance >= longTokenAmount, "LosslessV2Pool: INSUFFICIENT BALANCE"); // calculate withdraw principal amount uint256 shortPrincipalAmount = shortTokenAmount.mul(valuePerShortToken).div(PRECISION); uint256 longPrincipalAmount = longTokenAmount.mul(valuePerLongToken).div(PRECISION); // user withdraw will cause timestamp update -> reduce their goverance reward inPoolTimestamp[msg.sender] = block.timestamp; // burn user withdraw token _burnTokens(false, msg.sender, shortTokenAmount, longTokenAmount); /* pool status | isAToken | Operation lock T transfer aToken lock F redeem then transfer principal Token unlock T supply to aave then transfer aToken unlock F transfer principal token */ if (isAToken == false) { if (status.currState == PoolStatus.Locked) { _redeemFromAAVE(principalToken, shortPrincipalAmount.add(longPrincipalAmount)); } SafeERC20.safeTransfer(IERC20(principalToken), msg.sender, shortPrincipalAmount.add(longPrincipalAmount)); } else { if (status.currState == PoolStatus.Accepting) { _supplyToAAVE(principalToken, shortPrincipalAmount.add(longPrincipalAmount)); } SafeERC20.safeTransfer(IERC20(aToken), msg.sender, shortPrincipalAmount.add(longPrincipalAmount)); } emit Withdraw(isAToken, shortTokenAmount, longTokenAmount); } /** * @dev user can call this to shift share from long -> short, short -> long without withdrawing assets * @param fromLongToShort is user choosing to shift from long to short * @param swapTokenAmount the amount of token that user wishes to swap **/ function swap(bool fromLongToShort, uint256 swapTokenAmount) external override lock { require(status.currState == PoolStatus.Accepting, "LosslessV2Pool: WRONG STATUS"); uint256 shortTokenBalance = _shortToken.balanceOf(msg.sender); uint256 longTokenBalance = _longToken.balanceOf(msg.sender); uint256 tokenBalanceOfTargetPosition = fromLongToShort ? longTokenBalance : shortTokenBalance; // check user balance require(swapTokenAmount > 0 && swapTokenAmount <= tokenBalanceOfTargetPosition, "LosslessV2Pool: INSUFFICIENT BALANCE"); // reallocate user's share balance if (fromLongToShort == true) { // user wants to shift from long to short, so burn long share and increase short share _burnTokens(false, msg.sender, 0, swapTokenAmount); _mintTokens(false, msg.sender, swapTokenAmount.mul(valuePerLongToken).div(valuePerShortToken), 0); } else { // user wants to shift from short to long, so burn short share and increase long share _burnTokens(false, msg.sender, swapTokenAmount, 0); _mintTokens(false, msg.sender, 0, swapTokenAmount.mul(valuePerShortToken).div(valuePerLongToken)); } } /** * @dev sponsr can deposit and withdraw principals to the game * @param principalAmount amount of principal token **/ function sponsorDeposit(uint256 principalAmount) external override lock { require(status.currState != PoolStatus.Terminated, "LosslessV2Pool: POOL TERMINATED"); require(principalAmount > 0, "LosslessV2Pool: INVALID AMOUNT"); require(IERC20(principalToken).balanceOf(msg.sender) >= principalAmount, "LosslessV2Pool: INSUFFICIENT BALANCE"); // transfer asset first SafeERC20.safeTransferFrom(IERC20(principalToken), msg.sender, address(this), principalAmount); // check current game state if (status.currState == PoolStatus.Locked) { // if during the lock time // interact with AAVE to get the principal back _supplyToAAVE(principalToken, principalAmount); } // mint sponsor token _sponsorToken.mint(msg.sender, principalAmount); emit SponsorDeposit(principalAmount); } /** * @dev sponsr can deposit and withdraw principals to the game * @param sponsorTokenAmount amount of zero token **/ function sponsorWithdraw(uint256 sponsorTokenAmount) external override lock { require(sponsorTokenAmount > 0, "LosslessV2Pool: INVALID AMOUNT"); // burn user sponsor token _sponsorToken.burn(msg.sender, sponsorTokenAmount); // check current game state if (status.currState == PoolStatus.Locked) { // if during the lock time // interact with AAVE to get the principal back _redeemFromAAVE(principalToken, sponsorTokenAmount); } // transfer principal token SafeERC20.safeTransfer(IERC20(principalToken), msg.sender, sponsorTokenAmount); emit SponsorWithdraw(sponsorTokenAmount); } /** * @dev calculate each token's value * @param _totalShortPrincipal the total amount of short principal * @param _totalLongPrincipal the total amount of long principal **/ function _updateTokenValue(uint256 _totalShortPrincipal, uint256 _totalLongPrincipal) private { address feeTo = ILosslessV2Factory(factory).feeTo(); uint256 feePercent = ILosslessV2Factory(factory).feePercent(); uint256 fee = totalInterest.mul(feePercent).div(PRECISION); // if fee is on and feeTo been set if (feePercent != 0 && feeTo != address(0)) { totalInterest = totalInterest.sub(fee); SafeERC20.safeTransfer(IERC20(principalToken), feeTo, fee); } // update short/long token value if (status.isShortLastRoundWinner == true) { // short win _totalShortPrincipal = _totalShortPrincipal.add(totalInterest); valuePerShortToken = _totalShortPrincipal.mul(PRECISION).div(_shortToken.totalSupply()); } else if (status.isShortLastRoundWinner == false) { // long win _totalLongPrincipal = _totalLongPrincipal.add(totalInterest); valuePerLongToken = _totalLongPrincipal.mul(PRECISION).div(_longToken.totalSupply()); } emit UpdateTokenValue(valuePerShortToken, valuePerLongToken); } /** * @dev supply to aave protocol * @param _asset the address of the principal token * @param _amount the amount of the principal token wish to supply to AAVE **/ function _supplyToAAVE(address _asset, uint256 _amount) private { address lendingPoolAddress = ILendingPoolAddressesProvider(addressProvider).getLendingPool(); ILendingPool lendingPool = ILendingPool(lendingPoolAddress); SafeERC20.safeApprove(IERC20(_asset), address(lendingPool), _amount); lendingPool.deposit(_asset, _amount, address(this), 0); } /** * @dev redeem from aave protocol * @param _asset the address of the principal token * @param _amount the amount of the principal token wish to withdraw from AAVE **/ function _redeemFromAAVE(address _asset, uint256 _amount) private { // lendingPool address lendingPoolAddress = ILendingPoolAddressesProvider(addressProvider).getLendingPool(); ILendingPool lendingPool = ILendingPool(lendingPoolAddress); // protocol data provider aToken = _getATokenAddress(_asset); if (_amount == 0) { _amount = IERC20(aToken).balanceOf(address(this)); } lendingPool.withdraw(_asset, _amount, address(this)); } /** * @dev get atoken address * @param _asset the address of the principal token **/ function _getATokenAddress(address _asset) private view returns (address _aToken) { // protocol data provider uint8 number = 1; bytes32 id = bytes32(bytes1(number)); address dataProviderAddress = ILendingPoolAddressesProvider(addressProvider).getAddress(id); IProtocolDataProvider protocolDataProvider = IProtocolDataProvider(dataProviderAddress); (_aToken, , ) = protocolDataProvider.getReserveTokensAddresses(_asset); } /** * @dev mint token function to mint long and short token * @param _isPrincipal true: principal, false:long/short token amount * @param _to the destination account token got burned * @param _shortAmount the amount of the token to short * @param _longAmount the amount of the token to long **/ function _mintTokens( bool _isPrincipal, address _to, uint256 _shortAmount, uint256 _longAmount ) private { if (_isPrincipal == true) { // convert principal token amount to long/short token amount _shortAmount = _shortAmount.mul(PRECISION).div(valuePerShortToken); _longAmount = _longAmount.mul(PRECISION).div(valuePerLongToken); } if (_shortAmount != 0) { _shortToken.mint(_to, _shortAmount); } if (_longAmount != 0) { _longToken.mint(_to, _longAmount); } } /** * @dev burn token function to burn long and short token * @param _isPrincipal true: principal, false:long/short token amount * @param _from the destination account token got burned * @param _shortAmount the amount of the token to short * @param _longAmount the amount of the token to long **/ function _burnTokens( bool _isPrincipal, address _from, uint256 _shortAmount, uint256 _longAmount ) private { if (_isPrincipal == true) { // convert principal token amount to long/short token amount _shortAmount = _shortAmount.mul(PRECISION).div(valuePerShortToken); _longAmount = _longAmount.mul(PRECISION).div(valuePerLongToken); } if (_shortAmount != 0) { _shortToken.burn(_from, _shortAmount); } if (_longAmount != 0) { _longToken.burn(_from, _longAmount); } } /** * @dev communicate with oracle to get current trusted price * @return price ratio of bidToken * PRECISION / principalToken -> the result comes with precision **/ function _getPrice() private view returns (int256) { (uint80 roundID, int256 price, uint256 startedAt, uint256 timeStamp, uint80 answeredInRound) = priceFeed.latestRoundData(); return price; } /** * @dev return user's long token equivalent principal token amount **/ function userLongPrincipalBalance(address userAddress) external view override returns (uint256 userLongAmount) { userLongAmount = _longToken.balanceOf(userAddress).mul(valuePerLongToken).div(PRECISION); } /** * @dev return user's short token equivalent principal token amount **/ function userShortPrincipalBalance(address userAddress) external view override returns (uint256 userShortAmount) { userShortAmount = _shortToken.balanceOf(userAddress).mul(valuePerShortToken).div(PRECISION); } /** * @dev claim AAVE token rewards * @param stakedAAVEAddress_ stakedAAVE contract address * @param amount_ The amount of AAVE to be claimed. Use type(uint).max to claim all outstanding rewards for the user. */ function claimAAVE(address stakedAAVEAddress_, uint256 amount_ ) external override { require(stakedAAVEAddress_ != address(0), "LosslessV2Pool: stakedAAVEAddress_ ZERO ADDRESS"); address feeTo = ILosslessV2Factory(factory).feeTo(); require(feeTo != address(0), "LosslessV2Pool: feeTo ZERO ADDRESS"); IStakedToken stakedAAVE = IStakedToken(stakedAAVEAddress_); stakedAAVE.claimRewards(feeTo, amount_); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; interface ILosslessV2Factory { // event related event PoolCreated(address indexed bidToken, address indexed principalToken, address pool, uint256 allPoolLength); event PoolTerminated(address pool); event FeeToChanged(address feeTo); event FeePercentChanged(uint256 feePercent); event proposeDAOChange(address pendingDAO); event DAOChanged(address DAO); function allPools(uint256) external view returns (address pool); function allPoolsLength() external view returns (uint256); function getPool(address bidToken, address principalToken) external view returns (address pool); function isPoolActive(address) external view returns (bool); function getPoolShortToken(address) external view returns (address); function getPoolLongToken(address) external view returns (address); function getPoolSponsorToken(address) external view returns (address); function createPool( address bidToken, address principalToken, address addressProvider, address aggregator, uint256 biddingDuration, uint256 gamingDuration, string memory tokenName, string memory tokenSymbol ) external; // all fee related getter functions function feeTo() external view returns (address); function DAO() external view returns (address); function pendingDAO() external view returns (address); function feePercent() external view returns (uint256); // only admin functions // The default DAO is admin but admin can assign this role to others by calling `setDAO` function setFeeTo(address) external; function setFeePercent(uint256 _feePercent) external; function setPendingDAO(address _pendingDAO) external; function setDAO() external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor( string memory name_, string memory symbol_, uint8 decimals_ ) public { _name = name_; _symbol = symbol_; _decimals = decimals_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; interface ILosslessV2Pool { // defined and controls all game logic related variables struct GameStatus { bool isShortLastRoundWinner; // record whether last round winner bool isFirstUser; // check if the user is the first one to enter the game or not bool isFirstRound; // is this game the first round of the entire pool? uint256 gameRound; // count for showing current game round uint256 durationOfGame; // which should be 6 days in default uint256 durationOfBidding; // which should be 1 days in default uint256 lastUpdateTimestamp; // the timestamp when last game logic function been called int256 initialPrice; // game initial price int256 endPrice; // game end price PoolStatus currState; // current pool status } // token info for current pool struct PoolTokensInfo { address longToken; address shortToken; address sponsorToken; } // # ENUM FOR POOL STATUS /* PoolStatus Explaination ***** Locked ------ game period. interacting with compound Accepting --- users can adding or reducing the bet FirstGame --- only been used for the first round Terminated -- only when special cases admin decided to close the pool Notation ****** /name/ - status name [name] - function call name Workflow ******* /Accepting/ /Locked/ /Accepting/ /Terminated/ | | | | [startFirstRound] ---------> [startGame] -------> [endGame] ---> [poolTermination] ---------------> ^ | | | | record time -------------------- | /Accepting/ */ enum PoolStatus { FirstGame, Locked, Accepting, Terminated } // ## DEFINE USER OPERATION EVENTS event Deposit(uint256 shortPrincipalAmount, uint256 longPrincipalAmount); event Withdraw(bool isAToken, uint256 shortTokenAmount, uint256 longTokenAmount); event SponsorDeposit(uint256 principalAmount); event SponsorWithdraw(uint256 sponsorTokenAmount); // ## DEFINE GAME OPERATION EVENTS event UpdateTokenValue(uint256 valuePerShortToken, uint256 valuePerLongToken); event AnnounceWinner(bool isShortLastRoundWinner, int256 initialPrice, int256 endPrice); // ## PUBLIC VARIABLES function factory() external view returns (address); function bidToken() external view returns (address); function principalToken() external view returns (address); function aToken() external view returns (address); function addressProvider() external view returns (address); // ### GAME SETTING VARIABLES function inPoolTimestamp(address userAddress) external view returns (uint256); // ## STATE-CHANGING FUNCTION /* initialize: initialize the game startFirstRound: start the frist round logic startGame: start game -> pool lock supply principal to AAVE, get start game price endGame: end game -> pool unlock redeem fund to AAVE, get end game price poolTermination: terminate the pool, no more game, but user can still withdraw fund */ function initialize( address shortToken_, address longToken_, address sponsorToken_ ) external; function startFirstRound() external; // only be called to start the first Round function startGame() external; // called after bidding duration function endGame() external; // called after game duraion ///@dev admin only function poolTermination() external; // called after selectWinner only by admin // user actions in below, join game, add, reduce or withDraw all fund /* deposit: adding funds can be either just long or short or both withdraw: reduce funds can be either just long or short or both swap: change amount of tokens from long -> short / short -> long sponsorDeposit: deposit principal to the pool as interest sponsor sponsorWithdraw: withdraw sponsor donation from the pool */ function deposit(uint256 shortPrincipalAmount, uint256 longPrincipalAmount) external; function withdraw( bool isAToken, uint256 shortTokenAmount, uint256 longTokenAmount ) external; function swap(bool fromLongToShort, uint256 swapTokenAmount) external; function sponsorDeposit(uint256 principalAmount) external; function sponsorWithdraw(uint256 sponsorTokenAmount) external; function claimAAVE(address stakedAAVEAddress_, uint256 amount_ ) external; // view functions to return user balance function userLongPrincipalBalance(address userAddress) external view returns (uint256); function userShortPrincipalBalance(address userAddress) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @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 subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @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) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting 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) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface ILosslessV2Token is IERC20 { function mint(address to, uint256 amount) external returns (bool); function burn(address from, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; interface IPriceOracleGetter { function getAssetPrice(address _asset) external view returns (uint256); function getAssetsPrices(address[] calldata _assets) external view returns (uint256[] memory); function getSourceOfAsset(address _asset) external view returns (address); function getFallbackOracle() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; /** * @title LendingPoolAddressesProvider contract * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles * - Acting also as factory of proxies and admin of those, so with right to change its implementations * - Owned by the Aave Governance * @author Aave **/ interface ILendingPoolAddressesProvider { event MarketIdSet(string newMarketId); event LendingPoolUpdated(address indexed newAddress); event ConfigurationAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); function getMarketId() external view returns (string memory); function setMarketId(string calldata marketId) external; function setAddress(bytes32 id, address newAddress) external; function setAddressAsProxy(bytes32 id, address impl) external; function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); function setLendingPoolImpl(address pool) external; function getLendingPoolConfigurator() external view returns (address); function setLendingPoolConfiguratorImpl(address configurator) external; function getLendingPoolCollateralManager() external view returns (address); function setLendingPoolCollateralManager(address manager) external; function getPoolAdmin() external view returns (address); function setPoolAdmin(address admin) external; function getEmergencyAdmin() external view returns (address); function setEmergencyAdmin(address admin) external; function getPriceOracle() external view returns (address); function setPriceOracle(address priceOracle) external; function getLendingRateOracle() external view returns (address); function setLendingRateOracle(address lendingRateOracle) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import { ILendingPoolAddressesProvider } from "./ILendingPoolAddressesProvider.sol"; import { DataTypes } from "../core/libraries/DataTypes.sol"; interface ILendingPool { /** * @dev Emitted on deposit() * @param reserve The address of the underlying asset of the reserve * @param user The address initiating the deposit * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens * @param amount The amount deposited * @param referral The referral code used **/ event Deposit(address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint16 indexed referral); /** * @dev Emitted on withdraw() * @param reserve The address of the underlyng asset being withdrawn * @param user The address initiating the withdrawal, owner of aTokens * @param to Address that will receive the underlying * @param amount The amount to be withdrawn **/ event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); /** * @dev Emitted on borrow() and flashLoan() when debt needs to be opened * @param reserve The address of the underlying asset being borrowed * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just * initiator of the transaction on flashLoan() * @param onBehalfOf The address that will be getting the debt * @param amount The amount borrowed out * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable * @param borrowRate The numeric rate at which the user has borrowed * @param referral The referral code used **/ event Borrow( address indexed reserve, address user, address indexed onBehalfOf, uint256 amount, uint256 borrowRateMode, uint256 borrowRate, uint16 indexed referral ); /** * @dev Emitted on repay() * @param reserve The address of the underlying asset of the reserve * @param user The beneficiary of the repayment, getting his debt reduced * @param repayer The address of the user initiating the repay(), providing the funds * @param amount The amount repaid **/ event Repay(address indexed reserve, address indexed user, address indexed repayer, uint256 amount); /** * @dev Emitted on swapBorrowRateMode() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user swapping his rate mode * @param rateMode The rate mode that the user wants to swap to **/ event Swap(address indexed reserve, address indexed user, uint256 rateMode); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); /** * @dev Emitted on setUserUseReserveAsCollateral() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user enabling the usage as collateral **/ event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); /** * @dev Emitted on rebalanceStableBorrowRate() * @param reserve The address of the underlying asset of the reserve * @param user The address of the user for which the rebalance has been executed **/ event RebalanceStableBorrowRate(address indexed reserve, address indexed user); /** * @dev Emitted on flashLoan() * @param target The address of the flash loan receiver contract * @param initiator The address initiating the flash loan * @param asset The address of the asset being flash borrowed * @param amount The amount flash borrowed * @param premium The fee flash borrowed * @param referralCode The referral code used **/ event FlashLoan(address indexed target, address indexed initiator, address indexed asset, uint256 amount, uint256 premium, uint16 referralCode); /** * @dev Emitted when the pause is triggered. */ event Paused(); /** * @dev Emitted when the pause is lifted. */ event Unpaused(); /** * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via * LendingPoolCollateral manager using a DELEGATECALL * This allows to have the events in the generated ABI for LendingPool. * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator * @param liquidator The address of the liquidator * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ event LiquidationCall( address indexed collateralAsset, address indexed debtAsset, address indexed user, uint256 debtToCover, uint256 liquidatedCollateralAmount, address liquidator, bool receiveAToken ); /** * @dev Emitted when the state of a reserve is updated. NOTE: This event is actually declared * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it * gets added to the LendingPool ABI * @param reserve The address of the underlying asset of the reserve * @param liquidityRate The new liquidity rate * @param stableBorrowRate The new stable borrow rate * @param variableBorrowRate The new variable borrow rate * @param liquidityIndex The new liquidity index * @param variableBorrowIndex The new variable borrow index **/ event ReserveDataUpdated( address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex ); /** * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC * @param asset The address of the underlying asset to deposit * @param amount The amount to be deposited * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function deposit( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC * @param asset The address of the underlying asset to withdraw * @param amount The underlying amount to be withdrawn * - Send the value type(uint256).max in order to withdraw the whole aToken balance * @param to Address that will receive the underlying, same as msg.sender if the user * wants to receive it on his own wallet, or a different address if the beneficiary is a * different wallet * @return The final amount withdrawn **/ function withdraw( address asset, uint256 amount, address to ) external returns (uint256); /** * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower * already deposited enough collateral, or he was given enough allowance by a credit delegator on the * corresponding debt token (StableDebtToken or VariableDebtToken) * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet * and 100 stable/variable debt tokens, depending on the `interestRateMode` * @param asset The address of the underlying asset to borrow * @param amount The amount to be borrowed * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man * @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * if he has been given credit delegation allowance **/ function borrow( address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf ) external; /** * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address * @param asset The address of the borrowed underlying asset previously borrowed * @param amount The amount to repay * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed * @return The final amount repaid **/ function repay( address asset, uint256 amount, uint256 rateMode, address onBehalfOf ) external returns (uint256); /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed * @param rateMode The rate mode that the user wants to swap to **/ function swapBorrowRateMode(address asset, uint256 rateMode) external; /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: * 1. Usage ratio is above 95% * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been * borrowed at a stable rate and depositors are not earning enough * @param asset The address of the underlying asset borrowed * @param user The address of the user to be rebalanced **/ function rebalanceStableBorrowRate(address asset, address user) external; /** * @dev Allows depositors to enable/disable a specific deposited asset as collateral * @param asset The address of the underlying asset deposited * @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise **/ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external; /** * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1 * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation * @param user The address of the borrower getting liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants * to receive the underlying collateral asset directly **/ function liquidationCall( address collateralAsset, address debtAsset, address user, uint256 debtToCover, bool receiveAToken ) external; /** * @dev Allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration. * For further details please visit https://developers.aave.com * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface * @param assets The addresses of the assets being flash-borrowed * @param amounts The amounts amounts being flash-borrowed * @param modes Types of the debt to open if the flash loan is not returned: * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver * 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address * @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2 * @param params Variadic packed params to pass to the receiver as extra information * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man **/ function flashLoan( address receiverAddress, address[] calldata assets, uint256[] calldata amounts, uint256[] calldata modes, address onBehalfOf, bytes calldata params, uint16 referralCode ) external; /** * @dev Returns the user account data across all the reserves * @param user The address of the user * @return totalCollateralETH the total collateral in ETH of the user * @return totalDebtETH the total debt in ETH of the user * @return availableBorrowsETH the borrowing power left of the user * @return currentLiquidationThreshold the liquidation threshold of the user * @return ltv the loan to value of the user * @return healthFactor the current health factor of the user **/ function getUserAccountData(address user) external view returns ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ); function initReserve( address reserve, address aTokenAddress, address stableDebtAddress, address variableDebtAddress, address interestRateStrategyAddress ) external; function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) external; function setConfiguration(address reserve, uint256 configuration) external; /** * @dev Returns the configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The configuration of the reserve **/ function getConfiguration(address asset) external view returns (DataTypes.ReserveConfigurationMap memory); /** * @dev Returns the configuration of the user across all the reserves * @param user The user address * @return The configuration of the user **/ function getUserConfiguration(address user) external view returns (DataTypes.UserConfigurationMap memory); /** * @dev Returns the normalized income normalized income of the reserve * @param asset The address of the underlying asset of the reserve * @return The reserve's normalized income */ function getReserveNormalizedIncome(address asset) external view returns (uint256); /** * @dev Returns the normalized variable debt per unit of asset * @param asset The address of the underlying asset of the reserve * @return The reserve normalized variable debt */ function getReserveNormalizedVariableDebt(address asset) external view returns (uint256); /** * @dev Returns the state and configuration of the reserve * @param asset The address of the underlying asset of the reserve * @return The state of the reserve **/ function getReserveData(address asset) external view returns (DataTypes.ReserveData memory); function finalizeTransfer( address asset, address from, address to, uint256 amount, uint256 balanceFromAfter, uint256 balanceToBefore ) external; function getReservesList() external view returns (address[] memory); function getAddressesProvider() external view returns (ILendingPoolAddressesProvider); function setPause(bool val) external; function paused() external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import { ILendingPoolAddressesProvider } from "./ILendingPoolAddressesProvider.sol"; interface IProtocolDataProvider { struct TokenData { string symbol; address tokenAddress; } function ADDRESSES_PROVIDER() external view returns (ILendingPoolAddressesProvider); function getAllReservesTokens() external view returns (TokenData[] memory); function getAllATokens() external view returns (TokenData[] memory); function getReserveConfigurationData(address asset) external view returns ( uint256 decimals, uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, uint256 reserveFactor, bool usageAsCollateralEnabled, bool borrowingEnabled, bool stableBorrowRateEnabled, bool isActive, bool isFrozen ); function getReserveData(address asset) external view returns ( uint256 availableLiquidity, uint256 totalStableDebt, uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, uint256 averageStableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp ); function getUserReserveData(address asset, address user) external view returns ( uint256 currentATokenBalance, uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); function getReserveTokensAddresses(address asset) external view returns ( address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress ); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; interface IStakedToken { function stake(address to, uint256 amount) external; function redeem(address to, uint256 amount) external; function cooldown() external; function claimRewards(address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface AggregatorV3Interface { function decimals() external view returns ( uint8 ); function description() external view returns ( string memory ); function version() external view returns ( uint256 ); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData( uint80 _roundId ) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; interface KeeperCompatibleInterface { /** * @notice checks if the contract requires work to be done. * @param checkData data passed to the contract when checking for upkeep. * @return upkeepNeeded boolean to indicate whether the keeper should call * performUpkeep or not. * @return performData bytes that the keeper should call performUpkeep with, * if upkeep is needed. */ function checkUpkeep( bytes calldata checkData ) external returns ( bool upkeepNeeded, bytes memory performData ); /** * @notice Performs work on the contract. Executed by the keepers, via the registry. * @param performData is the data which was passed back from the checkData * simulation. */ function performUpkeep( bytes calldata performData ) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.6.12; library DataTypes { // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. struct ReserveData { //stores the reserve configuration ReserveConfigurationMap configuration; //the liquidity index. Expressed in ray uint128 liquidityIndex; //variable borrow index. Expressed in ray uint128 variableBorrowIndex; //the current supply rate. Expressed in ray uint128 currentLiquidityRate; //the current variable borrow rate. Expressed in ray uint128 currentVariableBorrowRate; //the current stable borrow rate. Expressed in ray uint128 currentStableBorrowRate; uint40 lastUpdateTimestamp; //tokens addresses address aTokenAddress; address stableDebtTokenAddress; address variableDebtTokenAddress; //address of the interest rate strategy address interestRateStrategyAddress; //the id of the reserve. Represents the position in the list of the active reserves uint8 id; } struct ReserveConfigurationMap { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } struct UserConfigurationMap { uint256 data; } enum InterestRateMode { NONE, STABLE, VARIABLE } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_DAO","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"DAO","type":"address"}],"name":"DAOChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feePercent","type":"uint256"}],"name":"FeePercentChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"feeTo","type":"address"}],"name":"FeeToChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bidToken","type":"address"},{"indexed":true,"internalType":"address","name":"principalToken","type":"address"},{"indexed":false,"internalType":"address","name":"pool","type":"address"},{"indexed":false,"internalType":"uint256","name":"allPoolLength","type":"uint256"}],"name":"PoolCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"PoolTerminated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pendingDAO","type":"address"}],"name":"proposeDAOChange","type":"event"},{"inputs":[],"name":"DAO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPoolsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bidToken","type":"address"},{"internalType":"address","name":"principalToken","type":"address"},{"internalType":"address","name":"addressProvider","type":"address"},{"internalType":"address","name":"aggregator","type":"address"},{"internalType":"uint256","name":"biddingDuration","type":"uint256"},{"internalType":"uint256","name":"gamingDuration","type":"uint256"},{"internalType":"string","name":"tokenName","type":"string"},{"internalType":"string","name":"tokenSymbol","type":"string"}],"name":"createPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"getPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getPoolLongToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getPoolShortToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getPoolSponsorToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPoolActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingDAO","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"setDAO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeTo","type":"address"}],"name":"setFeeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pendingDAO","type":"address"}],"name":"setPendingDAO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"terminatePool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405161606e38038061606e8339818101604052602081101561003357600080fd5b50516001600160a01b03811661007a5760405162461bcd60e51b815260040180806020018281038252602b815260200180616043602b913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055615f9a806100a96000396000f3fe60806040523480156200001157600080fd5b5060043610620001245760003560e01c80637fd6f15c11620000b1578063d7778f92116200007b578063d7778f9214620003f6578063e692e09f146200041f578063efde4e641462000448578063f46901ed1462000452578063fd686494146200047b5762000124565b80637fd6f15c146200036a5780637ffc3eab146200038657806398fabd3a14620003af578063a711e6a114620003b95762000124565b806341d1de9711620000f357806341d1de9714620002ef578063531aa03e146200030f578063723a7c0414620003405780637ce3489b146200034a5762000124565b8063017e7e5814620001295780630702f86c146200014f57806310bd1f4614620002bc57806318198c1714620002c6575b600080fd5b62000133620004a4565b604080516001600160a01b039092168252519081900360200190f35b620002ba60048036036101008110156200016857600080fd5b6001600160a01b038235811692602081013582169260408201358316926060830135169160808101359160a0820135919081019060e0810160c0820135640100000000811115620001b857600080fd5b820183602082011115620001cb57600080fd5b80359060200191846001830284011164010000000083111715620001ee57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156200024257600080fd5b8201836020820111156200025557600080fd5b803590602001918460018302840111640100000000831117156200027857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550620004b3945050505050565b005b6200013362000bf9565b6200013360048036036020811015620002de57600080fd5b50356001600160a01b031662000c08565b62000133600480360360208110156200030757600080fd5b503562000c23565b62000133600480360360408110156200032757600080fd5b506001600160a01b038135811691602001351662000c4b565b620002ba62000c71565b620002ba600480360360208110156200036257600080fd5b503562000d6a565b6200037462000e36565b60408051918252519081900360200190f35b62000133600480360360208110156200039e57600080fd5b50356001600160a01b031662000e3c565b6200013362000e57565b620003e260048036036020811015620003d157600080fd5b50356001600160a01b031662000e66565b604080519115158252519081900360200190f35b620003e2600480360360208110156200040e57600080fd5b50356001600160a01b031662000e7b565b62000133600480360360208110156200043757600080fd5b50356001600160a01b031662000fdc565b6200037462000ff7565b620002ba600480360360208110156200046a57600080fd5b50356001600160a01b031662000ffd565b620002ba600480360360208110156200049357600080fd5b50356001600160a01b0316620010ed565b6000546001600160a01b031681565b6001546001600160a01b0316331462000502576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b866001600160a01b0316886001600160a01b03161415620005555760405162461bcd60e51b815260040180806020018281038252602681526020018062005d8e6026913960400191505060405180910390fd5b6001600160a01b038816158015906200057657506001600160a01b03871615155b620005c8576040805162461bcd60e51b815260206004820152601f60248201527f4c6f73736c6573735632466163746f72793a205a45524f5f4144445245535300604482015290519081900360640190fd5b6001600160a01b0386166200060f5760405162461bcd60e51b815260040180806020018281038252603081526020018062005f046030913960400191505060405180910390fd5b6001600160a01b038516620006565760405162461bcd60e51b815260040180806020018281038252602a81526020018062005e78602a913960400191505060405180910390fd5b6001600160a01b0388811660009081526005602090815260408083208b851684529091529020541615620006d1576040805162461bcd60e51b815260206004820152601e60248201527f4c6f73736c6573735632466163746f72793a20504f4f4c5f4558495354530000604482015290519081900360640190fd5b60008411620007125760405162461bcd60e51b815260040180806020018281038252603281526020018062005ea26032913960400191505060405180910390fd5b60008311620007535760405162461bcd60e51b815260040180806020018281038252603181526020018062005f346031913960400191505060405180910390fd5b8151620007925760405162461bcd60e51b815260040180806020018281038252602e81526020018062005d60602e913960400191505060405180910390fd5b8051620007d15760405162461bcd60e51b815260040180806020018281038252603081526020018062005ed46030913960400191505060405180910390fd5b600454604080516020808201939093526bffffffffffffffffffffffff1960608c811b8216838501528b811b821660548401528a811b8216606884015289901b16607c8201528151607081830301815260909091019182905280519201919091209060009082908b908b908b908b908b908b906200084f90620016ba565b6001600160a01b0396871681529486166020860152928516604080860191909152919094166060840152608083019390935260a08201529051829181900360c001906000f5905080158015620008a9573d6000803e3d6000fd5b50905060008060006200092687878e6001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620008f157600080fd5b505afa15801562000906573d6000803e3d6000fd5b505050506040513d60208110156200091d57600080fd5b505187620011dd565b925092509250836001600160a01b031663c0c53b8b8484846040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b03168152602001826001600160a01b031681526020019350505050600060405180830381600087803b1580156200099e57600080fd5b505af1158015620009b3573d6000803e3d6000fd5b5050505083600560008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055506004849080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b03160217905550600160066000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508260076000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508160086000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508060096000866001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508b6001600160a01b03168d6001600160a01b03167febbbe9dc3a19d2f959ac76ac0372b4983cdfb945f5d6aef4873c36fabb2ba8aa8660048054905060405180836001600160a01b031681526020018281526020019250505060405180910390a350505050505050505050505050565b6002546001600160a01b031681565b6009602052600090815260409020546001600160a01b031681565b6004818154811062000c3157fe5b6000918252602090912001546001600160a01b0316905081565b60056020908152600092835260408084209091529082529020546001600160a01b031681565b6001546001600160a01b0316331462000cc0576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b6002546001600160a01b031662000d095760405162461bcd60e51b815260040180806020018281038252602f81526020018062005e49602f913960400191505060405180910390fd5b60028054600180546001600160a01b038084166001600160a01b03199283161792839055921690925560408051929091168252517f7a62ea533b501818ff8d9bde48cb1382a6df937b9339fe41e7d9a18db20e3e86916020908290030190a1565b6001546001600160a01b0316331462000db9576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b612710811062000dfb5760405162461bcd60e51b815260040180806020018281038252603981526020018062005db46039913960400191505060405180910390fd5b60038190556040805182815290517f91955c12515f4eb8f1ff79df82d1933ff11b6d3b9a3019c6568840616ec36a749181900360200190a150565b60035481565b6008602052600090815260409020546001600160a01b031681565b6001546001600160a01b031681565b60066020526000908152604090205460ff1681565b6001546000906001600160a01b0316331462000ecd576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b6001600160a01b03821660009081526006602052604090205460ff16151560011462000f2b5760405162461bcd60e51b815260040180806020018281038252602681526020018062005e236026913960400191505060405180910390fd5b816001600160a01b0316638fe688556040518163ffffffff1660e01b8152600401600060405180830381600087803b15801562000f6757600080fd5b505af115801562000f7c573d6000803e3d6000fd5b5050506001600160a01b038316600081815260066020908152604091829020805460ff19169055815192835290517ffdf10f6f014781f99c9ab5ae596e88402efac50b7fa92bf0b75d36e46fe35bf59350918290030190a1506001919050565b6007602052600090815260409020546001600160a01b031681565b60045490565b6001546001600160a01b031633146200104c576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b6001600160a01b038116620010935760405162461bcd60e51b815260040180806020018281038252603081526020018062005d306030913960400191505060405180910390fd5b600080546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f3dedba2a214b4fff9bf20fc473c114824654e0bc70512b4a92f6d5978763c28d916020908290030190a150565b6001546001600160a01b031633146200113c576040805162461bcd60e51b815260206004820152601c602482015260008051602062005d10833981519152604482015290519081900360640190fd5b6001600160a01b038116620011835760405162461bcd60e51b815260040180806020018281038252603681526020018062005ded6036913960400191505060405180910390fd5b600280546001600160a01b0319166001600160a01b03838116919091179182905560408051929091168252517f72aef41d8c66e458acdacaa2c7361620f63d89f84f6a9ca6eb1ba92bae0fd7a0916020908290030190a150565b600080806001600160a01b038416620012285760405162461bcd60e51b815260040180806020018281038252603081526020018062005f046030913960400191505060405180910390fd5b62001320876040516020018080611cdd60f21b81525060020182805190602001908083835b602083106200126e5780518252601f1990920191602091820191016200124d565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052876040516020018080611cdd60f21b81525060020182805190602001908083835b60208310620012e45780518252601f199092019160209182019101620012c3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528787620014a6565b9250620013dd876040516020018080616c6760f01b81525060020182805190602001908083835b60208310620013685780518252601f19909201916020918201910162001347565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052876040516020018080616c6760f01b815250600201828051906020019080838360208310620012e45780518252601f199092019160209182019101620012c3565b91506200149a87604051602001808061073760f41b81525060020182805190602001908083835b60208310620014255780518252601f19909201916020918201910162001404565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405287604051602001808061073760f41b815250600201828051906020019080838360208310620012e45780518252601f199092019160209182019101620012c3565b90509450945094915050565b600080858585856040516020018085805190602001908083835b60208310620014e15780518252601f199092019160209182019101620014c0565b51815160209384036101000a600019018019909216911617905287519190930192870191508083835b602083106200152b5780518252601f1990920191602091820191016200150a565b6001836020036101000a0380198251168184511680821785525050505050509050018360ff1660f81b8152600101826001600160a01b031660601b8152601401945050505050604051602081830303815290604052805190602001209050600081878787876040516200159e90620016c8565b60ff831660408201526001600160a01b038216606082015260808082528551908201528451819060208083019160a084019189019080838360005b83811015620015f3578181015183820152602001620015d9565b50505050905090810190601f168015620016215780820380516001836020036101000a031916815260200191505b50838103825286518152865160209182019188019080838360005b83811015620016565781810151838201526020016200163c565b50505050905090810190601f168015620016845780820380516001836020036101000a031916815260200191505b5096505050505050508190604051809103906000f5905080158015620016ae573d6000803e3d6000fd5b50979650505050505050565b6134c380620016d783390190565b6111768062004b9a8339019056fe608060405261271060068190556007556017805460ff60a01b1916600160a01b1790553480156200002f57600080fd5b50604051620034c3380380620034c3833981810160405260c08110156200005557600080fd5b508051602082015160408301516060840151608085015160a09095015160008054336001600160a01b0319918216179091556001805482166001600160a01b0380891691909117909155600280548316828816179081905560048054909316828716179092559596949593949293620000cf91166200013d565b600380546001600160a01b039283166001600160a01b03199182161790915560058054959092169416939093179092556001600a55600c55600b55505042600d55506009805461ff001962ff0000199091166201000017166101001790556010805460ff191690556200024f565b60048054604080516321f8a72160e01b8152600160f81b9381018490529051600093600193909285926001600160a01b03909216916321f8a72191602480820192602092909190829003018186803b1580156200019957600080fd5b505afa158015620001ae573d6000803e3d6000fd5b505050506040513d6020811015620001c557600080fd5b5051604080516334924edb60e21b81526001600160a01b038881166004830152915192935083929183169163d2493b6c91602480820192606092909190829003018186803b1580156200021757600080fd5b505afa1580156200022c573d6000803e3d6000fd5b505050506040513d60608110156200024357600080fd5b50519695505050505050565b613264806200025f6000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c8063a0c1f15e116100f9578063c45a015511610097578063dfafd4fd11610071578063dfafd4fd1461053f578063e2bbb15814610547578063fb5dfe781461056a578063fdd89a3414610590576101a9565b8063c45a015514610527578063d65ab5f21461052f578063dbc162de14610537576101a9565b8063bb1c9f7f116100d3578063bb1c9f7f1461049e578063bb6e179614610496578063c037646a146104ca578063c0c53b8b146104ef576101a9565b8063a0c1f15e14610486578063aa18ca921461048e578063aaf5eb6814610496576101a9565b80634585e33b116101665780636cbc2ded116101405780636cbc2ded1461035f5780636e04ff0d14610367578063889c0bbd146104585780638fe688551461047e576101a9565b80634585e33b146102ac5780634d5bb1bb1461031c5780635785c18c14610342576101a9565b8063200d2ed2146101ae57806324294b1f1461021c5780632954018c14610226578063344846dd1461024a57806334e08db5146102675780633b3bbc9c14610292575b600080fd5b6101b66105c3565b604051808b151581526020018a15158152602001891515815260200188815260200187815260200186815260200185815260200184815260200183815260200182600381111561020257fe5b81526020019a505050505050505050505060405180910390f35b610224610603565b005b61022e6106df565b604080516001600160a01b039092168252519081900360200190f35b6102246004803603602081101561026057600080fd5b50356106ee565b6102246004803603606081101561027d57600080fd5b5080351515906020810135906040013561089c565b61029a610bfe565b60408051918252519081900360200190f35b610224600480360360208110156102c257600080fd5b8101906020810181356401000000008111156102dd57600080fd5b8201836020820111156102ef57600080fd5b8035906020019184600183028401116401000000008311171561031157600080fd5b509092509050610c04565b61029a6004803603602081101561033257600080fd5b50356001600160a01b0316610c7e565b6102246004803603602081101561035857600080fd5b5035610c90565b610224610f5a565b6103d76004803603602081101561037d57600080fd5b81019060208101813564010000000081111561039857600080fd5b8201836020820111156103aa57600080fd5b803590602001918460018302840111640100000000831117156103cc57600080fd5b5090925090506113ba565b60405180831515815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561041c578181015183820152602001610404565b50505050905090810190601f1680156104495780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61029a6004803603602081101561046e57600080fd5b50356001600160a01b0316611480565b6102246114e5565b61022e6115ab565b61029a6115ba565b61029a6115c0565b610224600480360360408110156104b457600080fd5b506001600160a01b0381351690602001356115c6565b610224600480360360408110156104e057600080fd5b5080351515906020013561173d565b6102246004803603606081101561050557600080fd5b506001600160a01b0381358116916020810135821691604090910135166119d6565b61022e611a96565b610224611aa5565b61022e611dc8565b61022e611dd7565b6102246004803603604081101561055d57600080fd5b5080359060200135611de6565b61029a6004803603602081101561058057600080fd5b50356001600160a01b03166120a2565b610598612101565b604080516001600160a01b039485168152928416602084015292168183015290519081900360600190f35b600954600a54600b54600c54600d54600e54600f5460105460ff80891698610100810482169862010000909104821697909690959094909390929091168a565b60095462010000900460ff161515600114610665576040805162461bcd60e51b815260206004820181905260248201527f4c6f73736c6573735632506f6f6c3a204e4f5420464952535420524f554e4421604482015290519081900360640190fd5b600060105460ff16600381111561067857fe5b146106b8576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b42600d556009805462ff000019169055601080546002919060ff19166001835b0217905550565b6004546001600160a01b031681565b601754600160a01b900460ff16151560011461073f576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b191690558061078c576040805162461bcd60e51b815260206004820152601e602482015260008051602061314b833981519152604482015290519081900360640190fd5b60175460408051632770a7eb60e21b81523360048201526024810184905290516001600160a01b0390921691639dc29fac916044808201926020929091908290030181600087803b1580156107e057600080fd5b505af11580156107f4573d6000803e3d6000fd5b505050506040513d602081101561080a57600080fd5b506001905060105460ff16600381111561082057fe5b141561083c5760025461083c906001600160a01b03168261211e565b600254610853906001600160a01b031633836122c8565b6040805182815290517f53f39bc00c1c01fadfe8bb9bd4d3398572c1cd9b0061bebcdd8c1abd4e4e21d19181900360200190a1506017805460ff60a01b1916600160a01b179055565b601754600160a01b900460ff1615156001146108ed576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055811515806109085750600081115b610947576040805162461bcd60e51b815260206004820152601e602482015260008051602061314b833981519152604482015290519081900360640190fd5b601554604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561099257600080fd5b505afa1580156109a6573d6000803e3d6000fd5b505050506040513d60208110156109bc57600080fd5b5051601654604080516370a0823160e01b815233600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610a0f57600080fd5b505afa158015610a23573d6000803e3d6000fd5b505050506040513d6020811015610a3957600080fd5b50519050838210801590610a4d5750828110155b610a885760405162461bcd60e51b815260040180806020018281038252602481526020018061320b6024913960400191505060405180910390fd5b6000610aab612710610aa56006548861231f90919063ffffffff16565b9061237f565b90506000610aca612710610aa56007548861231f90919063ffffffff16565b336000818152601460205260408120429055919250610aeb919088886123e6565b86610b4d57600160105460ff166003811115610b0357fe5b1415610b2857600254610b28906001600160a01b0316610b238484612508565b61211e565b600254610b48906001600160a01b031633610b438585612508565b6122c8565b610ba0565b600260105460ff166003811115610b6057fe5b1415610b8557600254610b85906001600160a01b0316610b808484612508565b612562565b600354610ba0906001600160a01b031633610b438585612508565b6040805188151581526020810188905280820187905290517ffedb0622d5d5fa46cc706a5c2c169f2bf2eb31a59ff2f70cef3096376f58c2c09181900360600190a150506017805460ff60a01b1916600160a01b1790555050505050565b60065481565b601054600d54600b54600c5460ff909316926002846003811115610c2457fe5b148015610c395750610c368382612508565b42115b15610c4657610c46611aa5565b6001846003811115610c5457fe5b148015610c695750610c668383612508565b42115b15610c7657610c76610f5a565b505050505050565b60146020526000908152604090205481565b601754600160a01b900460ff161515600114610ce1576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055600360105460ff166003811115610d0157fe5b1415610d54576040805162461bcd60e51b815260206004820152601f60248201527f4c6f73736c6573735632506f6f6c3a20504f4f4c205445524d494e4154454400604482015290519081900360640190fd5b60008111610d97576040805162461bcd60e51b815260206004820152601e602482015260008051602061314b833981519152604482015290519081900360640190fd5b600254604080516370a0823160e01b8152336004820152905183926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015610de157600080fd5b505afa158015610df5573d6000803e3d6000fd5b505050506040513d6020811015610e0b57600080fd5b50511015610e4a5760405162461bcd60e51b815260040180806020018281038252602481526020018061320b6024913960400191505060405180910390fd5b600254610e62906001600160a01b0316333084612648565b600160105460ff166003811115610e7557fe5b1415610e9157600254610e91906001600160a01b031682612562565b601754604080516340c10f1960e01b81523360048201526024810184905290516001600160a01b03909216916340c10f19916044808201926020929091908290030181600087803b158015610ee557600080fd5b505af1158015610ef9573d6000803e3d6000fd5b505050506040513d6020811015610f0f57600080fd5b50506040805182815290517f40b61effeb22345307b6b4acfbb4580925caf61a4b62d8672e9f3d1214d3479d9181900360200190a1506017805460ff60a01b1916600160a01b179055565b601754600160a01b900460ff161515600114610fab576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055600b54600d54610fc791612508565b8042116110055760405162461bcd60e51b81526004018080602001828103825260278152602001806130d46027913960400191505060405180910390fd5b600160105460ff16600381111561101857fe5b14611058576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b600a54611066906001612508565b600a5542600d556009805461ff00191661010017905560108054600260ff199091168117909155546110a2906001600160a01b0316600061211e565b6110aa6126a2565b600f819055600e54136110c6576009805460ff191690556110d4565b6009805460ff191660011790555b6000611162612710610aa5600654601560009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561113057600080fd5b505afa158015611144573d6000803e3d6000fd5b505050506040513d602081101561115a57600080fd5b50519061231f565b905060006111c0612710610aa5600754601660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561113057600080fd5b9050600061121e612710610aa5612710601760009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561113057600080fd5b9050600061123661122f8484612508565b8590612508565b600254604080516370a0823160e01b8152306004820152905192935083926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561128657600080fd5b505afa15801561129a573d6000803e3d6000fd5b505050506040513d60208110156112b057600080fd5b505110156112c2576000600855611349565b600254604080516370a0823160e01b815230600482015290516113459284926001600160a01b03909116916370a0823191602480820192602092909190829003018186803b15801561131357600080fd5b505afa158015611327573d6000803e3d6000fd5b505050506040513d602081101561133d57600080fd5b505190612732565b6008555b611353848461278f565b600954600e54600f546040805160ff90941615158452602084019290925282820152517f363f3c6d2f590883f657a36adeb0d1b0440383e505ebfc904e41834f2c6eba889181900360600190a150506017805460ff60a01b1916600160a01b179055505050565b601054600d54600b54600c5460009360609360ff90911692909160028460038111156113e257fe5b1480156113f757506113f48382612508565b42115b15611405576001955061143b565b600184600381111561141357fe5b14801561142857506114258383612508565b42115b15611436576001955061143b565b600095505b87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250989b929a509198505050505050505050565b600754601654604080516370a0823160e01b81526001600160a01b03858116600483015291516000946114df9461271094610aa59492939116916370a08231916024808301926020929190829003018186803b15801561113057600080fd5b92915050565b6000546001600160a01b03163314611544576040805162461bcd60e51b815260206004820152601f60248201527f4c6f73736c6573735632466163746f72793a20464143544f5259204f4e4c5900604482015290519081900360640190fd5b600260105460ff16600381111561155757fe5b14611597576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b601080546003919060ff19166001836106d8565b6003546001600160a01b031681565b60075481565b61271081565b6001600160a01b03821661160b5760405162461bcd60e51b815260040180806020018281038252602f81526020018061311c602f913960400191505060405180910390fd5b60008060009054906101000a90046001600160a01b03166001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b15801561165a57600080fd5b505afa15801561166e573d6000803e3d6000fd5b505050506040513d602081101561168457600080fd5b505190506001600160a01b0381166116cd5760405162461bcd60e51b815260040180806020018281038252602281526020018061308c6022913960400191505060405180910390fd5b604080516309a99b4f60e41b81526001600160a01b0383811660048301526024820185905291518592831691639a99b4f091604480830192600092919082900301818387803b15801561171f57600080fd5b505af1158015611733573d6000803e3d6000fd5b5050505050505050565b601754600160a01b900460ff16151560011461178e576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055600260105460ff1660038111156117ae57fe5b146117ee576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b601554604080516370a0823160e01b815233600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561183957600080fd5b505afa15801561184d573d6000803e3d6000fd5b505050506040513d602081101561186357600080fd5b5051601654604080516370a0823160e01b815233600482015290519293506000926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156118b657600080fd5b505afa1580156118ca573d6000803e3d6000fd5b505050506040513d60208110156118e057600080fd5b505190506000846118f157826118f3565b815b90506000841180156119055750808411155b6119405760405162461bcd60e51b815260040180806020018281038252602481526020018061320b6024913960400191505060405180910390fd5b60018515151415611986576119596000336000876123e6565b61198160003361197a600654610aa56007548a61231f90919063ffffffff16565b6000612a82565b6119bc565b6119946000338660006123e6565b6119bc60003360006119b7600754610aa56006548b61231f90919063ffffffff16565b612a82565b50506017805460ff60a01b1916600160a01b179055505050565b6000546001600160a01b03163314611a35576040805162461bcd60e51b815260206004820152601f60248201527f4c6f73736c6573735632466163746f72793a20464143544f5259204f4e4c5900604482015290519081900360640190fd5b601280546001600160a01b039485166001600160a01b03199182168117909255601180549486169482168517905560138054939095169281168317909455601580548516909117905560168054841690921790915560178054909216179055565b6000546001600160a01b031681565b601754600160a01b900460ff161515600114611af6576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055600c54600d54611b1291612508565b804211611b505760405162461bcd60e51b81526004018080602001828103825260278152602001806130d46027913960400191505060405180910390fd5b600260105460ff166003811115611b6357fe5b14611ba3576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b601560009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611bf157600080fd5b505afa158015611c05573d6000803e3d6000fd5b505050506040513d6020811015611c1b57600080fd5b505115801590611ca35750601660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c7457600080fd5b505afa158015611c88573d6000803e3d6000fd5b505050506040513d6020811015611c9e57600080fd5b505115155b611cf4576040805162461bcd60e51b815260206004820152601f60248201527f4c6f73736c6573735632506f6f6c3a204e4f2046554e4420494e20504f4f4c00604482015290519081900360640190fd5b42600d5560095460ff61010090910416151560011415611d2557611d166126a2565b600e556009805461ff00191690555b6010805460ff19166001179055600254604080516370a0823160e01b81523060048201529051611db2926001600160a01b03169182916370a0823191602480820192602092909190829003018186803b158015611d8157600080fd5b505afa158015611d95573d6000803e3d6000fd5b505050506040513d6020811015611dab57600080fd5b5051612562565b506017805460ff60a01b1916600160a01b179055565b6002546001600160a01b031681565b6001546001600160a01b031681565b601754600160a01b900460ff161515600114611e37576040805162461bcd60e51b81526020600482015260166024820152600080516020613195833981519152604482015290519081900360640190fd5b6017805460ff60a01b19169055600260105460ff166003811115611e5757fe5b14611e97576040805162461bcd60e51b815260206004820152601c60248201526000805160206131b5833981519152604482015290519081900360640190fd5b6000821180611ea65750600081115b611ee5576040805162461bcd60e51b815260206004820152601e602482015260008051602061314b833981519152604482015290519081900360640190fd5b60095460ff61010090910416151560011415611f1257611f036126a2565b600e556009805461ff00191690555b601554604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611f5d57600080fd5b505afa158015611f71573d6000803e3d6000fd5b505050506040513d6020811015611f8757600080fd5b505115801561200a5750601654604080516370a0823160e01b815233600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015611fdc57600080fd5b505afa158015611ff0573d6000803e3d6000fd5b505050506040513d602081101561200657600080fd5b5051155b15612022573360009081526014602052604090204290555b600254612043906001600160a01b0316333061203e8686612508565b612648565b6120506001338484612a82565b604080518381526020810183905281517fa3af609bf46297028ce551832669030f9effef2b02606d02cbbcc40fe6b47c55929181900390910190a150506017805460ff60a01b1916600160a01b179055565b600654601554604080516370a0823160e01b81526001600160a01b03858116600483015291516000946114df9461271094610aa59492939116916370a08231916024808301926020929190829003018186803b15801561113057600080fd5b6011546012546013546001600160a01b0392831692918216911683565b6000600460009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561216e57600080fd5b505afa158015612182573d6000803e3d6000fd5b505050506040513d602081101561219857600080fd5b50519050806121a684612b9e565b600380546001600160a01b0319166001600160a01b03929092169190911790558261224557600354604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561221657600080fd5b505afa15801561222a573d6000803e3d6000fd5b505050506040513d602081101561224057600080fd5b505192505b60408051631a4ca37b60e21b81526001600160a01b038681166004830152602482018690523060448301529151918316916369328dec916064808201926020929091908290030181600087803b15801561229e57600080fd5b505af11580156122b2573d6000803e3d6000fd5b505050506040513d6020811015610c7657600080fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261231a908490612caa565b505050565b60008261232e575060006114df565b8282028284828161233b57fe5b04146123785760405162461bcd60e51b81526004018080602001828103825260218152602001806130fb6021913960400191505060405180910390fd5b9392505050565b60008082116123d5576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816123de57fe5b049392505050565b6001841515141561241d5760065461240490610aa58461271061231f565b60075490925061241a90610aa58361271061231f565b90505b81156124a65760155460408051632770a7eb60e21b81526001600160a01b0386811660048301526024820186905291519190921691639dc29fac9160448083019260209291908290030181600087803b15801561247957600080fd5b505af115801561248d573d6000803e3d6000fd5b505050506040513d60208110156124a357600080fd5b50505b80156125025760165460408051632770a7eb60e21b81526001600160a01b0386811660048301526024820185905291519190921691639dc29fac9160448083019260209291908290030181600087803b15801561229e57600080fd5b50505050565b600082820183811015612378576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000600460009054906101000a90046001600160a01b03166001600160a01b0316630261bf8b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125b257600080fd5b505afa1580156125c6573d6000803e3d6000fd5b505050506040513d60208110156125dc57600080fd5b50519050806125ec848285612d5b565b6040805163e8eda9df60e01b81526001600160a01b0386811660048301526024820186905230604483015260006064830181905292519084169263e8eda9df926084808201939182900301818387803b15801561171f57600080fd5b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612502908590612caa565b600080600080600080600560009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b1580156126f957600080fd5b505afa15801561270d573d6000803e3d6000fd5b505050506040513d60a081101561272357600080fd5b50602001519550505050505090565b600082821115612789576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60008060009054906101000a90046001600160a01b03166001600160a01b031663017e7e586040518163ffffffff1660e01b815260040160206040518083038186803b1580156127de57600080fd5b505afa1580156127f2573d6000803e3d6000fd5b505050506040513d602081101561280857600080fd5b50516000805460408051631ff5bc5760e21b8152905193945091926001600160a01b0390911691637fd6f15c916004808301926020929190829003018186803b15801561285457600080fd5b505afa158015612868573d6000803e3d6000fd5b505050506040513d602081101561287e57600080fd5b505160085490915060009061289b9061271090610aa5908561231f565b905081158015906128b457506001600160a01b03831615155b156128e0576008546128c69082612732565b6008556002546128e0906001600160a01b031684836122c8565b60095460ff16151560011415612991576008546128fe908690612508565b9450612989601560009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561295157600080fd5b505afa158015612965573d6000803e3d6000fd5b505050506040513d602081101561297b57600080fd5b5051610aa58761271061231f565b600655612a38565b60095460ff16612a38576008546129a9908590612508565b9350612a34601660009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156129fc57600080fd5b505afa158015612a10573d6000803e3d6000fd5b505050506040513d6020811015612a2657600080fd5b5051610aa58661271061231f565b6007555b7f3b18646b3983733450bdfbad0272e569b970aa8e53a92ab463689709f0bc4c0e600654600754604051808381526020018281526020019250505060405180910390a15050505050565b60018415151415612ab957600654612aa090610aa58461271061231f565b600754909250612ab690610aa58361271061231f565b90505b8115612b4257601554604080516340c10f1960e01b81526001600160a01b03868116600483015260248201869052915191909216916340c10f199160448083019260209291908290030181600087803b158015612b1557600080fd5b505af1158015612b29573d6000803e3d6000fd5b505050506040513d6020811015612b3f57600080fd5b50505b801561250257601654604080516340c10f1960e01b81526001600160a01b03868116600483015260248201859052915191909216916340c10f199160448083019260209291908290030181600087803b15801561229e57600080fd5b60048054604080516321f8a72160e01b8152600160f81b9381018490529051600093600193909285926001600160a01b03909216916321f8a72191602480820192602092909190829003018186803b158015612bf957600080fd5b505afa158015612c0d573d6000803e3d6000fd5b505050506040513d6020811015612c2357600080fd5b5051604080516334924edb60e21b81526001600160a01b038881166004830152915192935083929183169163d2493b6c91602480820192606092909190829003018186803b158015612c7457600080fd5b505afa158015612c88573d6000803e3d6000fd5b505050506040513d6060811015612c9e57600080fd5b50519695505050505050565b6060612cff826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612e6e9092919063ffffffff16565b80519091501561231a57808060200190516020811015612d1e57600080fd5b505161231a5760405162461bcd60e51b815260040180806020018281038252602a81526020018061316b602a913960400191505060405180910390fd5b801580612de1575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015612db357600080fd5b505afa158015612dc7573d6000803e3d6000fd5b505050506040513d6020811015612ddd57600080fd5b5051155b612e1c5760405162461bcd60e51b81526004018080602001828103825260368152602001806131d56036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261231a908490612caa565b6060612e7d8484600085612e85565b949350505050565b606082471015612ec65760405162461bcd60e51b81526004018080602001828103825260268152602001806130ae6026913960400191505060405180910390fd5b612ecf85612fe1565b612f20576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b60006060866001600160a01b031685876040518082805190602001908083835b60208310612f5f5780518252601f199092019160209182019101612f40565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612fc1576040519150601f19603f3d011682016040523d82523d6000602084013e612fc6565b606091505b5091509150612fd6828286612fe7565b979650505050505050565b3b151590565b60608315612ff6575081612378565b8251156130065782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613050578181015183820152602001613038565b50505050905090810190601f16801561307d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe4c6f73736c6573735632506f6f6c3a20666565546f205a45524f2041444452455353416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4c6f73736c6573735632506f6f6c3a20494e56414c49442054494d455354414d50204146544552536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774c6f73736c6573735632506f6f6c3a207374616b656441415645416464726573735f205a45524f20414444524553534c6f73736c6573735632506f6f6c3a20494e56414c494420414d4f554e5400005361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565644c6f73736c6573735632506f6f6c3a204c4f434b4544000000000000000000004c6f73736c6573735632506f6f6c3a2057524f4e4720535441545553000000005361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e63654c6f73736c6573735632506f6f6c3a20494e53554646494349454e542042414c414e4345a2646970667358221220d5b92d4419ee56a0e9b1e93eae0179a294aa2864eef49bd14249526ee0425bee64736f6c634300060c003360806040523480156200001157600080fd5b506040516200117638038062001176833981810160405260808110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b9083019060208201858111156200006e57600080fd5b82516401000000008111828201881017156200008957600080fd5b82525081516020918201929091019080838360005b83811015620000b85781810151838201526020016200009e565b50505050905090810190601f168015620000e65780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200010a57600080fd5b9083019060208201858111156200012057600080fd5b82516401000000008111828201881017156200013b57600080fd5b82525081516020918201929091019080838360005b838110156200016a57818101518382015260200162000150565b50505050905090810190601f168015620001985780820380516001836020036101000a031916815260200191505b506040908152602082810151929091015186519294509250859185918591620001c891600391908601906200026c565b508151620001de9060049060208501906200026c565b506005805460ff191660ff9290921691909117905550506001600160a01b0381166200023c5760405162461bcd60e51b815260040180806020018281038252602d81526020018062001149602d913960400191505060405180910390fd5b600580546001600160a01b0390921661010002610100600160a81b03199092169190911790555062000308915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002af57805160ff1916838001178555620002df565b82800160010185558215620002df579182015b82811115620002df578251825591602001919060010190620002c2565b50620002ed929150620002f1565b5090565b5b80821115620002ed5760008155600101620002f2565b610e3180620003186000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806370a082311161008c578063a457c2d711610066578063a457c2d7146102cc578063a9059cbb146102f8578063b86a1fb214610324578063dd62ed3e14610348576100ea565b806370a082311461027257806395d89b41146102985780639dc29fac146102a0576100ea565b806323b872dd116100c857806323b872dd146101c6578063313ce567146101fc578063395093511461021a57806340c10f1914610246576100ea565b806306fdde03146100ef578063095ea7b31461016c57806318160ddd146101ac575b600080fd5b6100f7610376565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610131578181015183820152602001610119565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101986004803603604081101561018257600080fd5b506001600160a01b03813516906020013561040c565b604080519115158252519081900360200190f35b6101b4610429565b60408051918252519081900360200190f35b610198600480360360608110156101dc57600080fd5b506001600160a01b0381358116916020810135909116906040013561042f565b6102046104b6565b6040805160ff9092168252519081900360200190f35b6101986004803603604081101561023057600080fd5b506001600160a01b0381351690602001356104bf565b6101986004803603604081101561025c57600080fd5b506001600160a01b03813516906020013561050d565b6101b46004803603602081101561028857600080fd5b50356001600160a01b031661057e565b6100f7610599565b610198600480360360408110156102b657600080fd5b506001600160a01b0381351690602001356105fa565b610198600480360360408110156102e257600080fd5b506001600160a01b03813516906020013561066b565b6101986004803603604081101561030e57600080fd5b506001600160a01b0381351690602001356106d3565b61032c6106e7565b604080516001600160a01b039092168252519081900360200190f35b6101b46004803603604081101561035e57600080fd5b506001600160a01b03813581169160200135166106fb565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104025780601f106103d757610100808354040283529160200191610402565b820191906000526020600020905b8154815290600101906020018083116103e557829003601f168201915b5050505050905090565b6000610420610419610726565b848461072a565b50600192915050565b60025490565b600061043c848484610816565b6104ac84610448610726565b6104a785604051806060016040528060288152602001610d45602891396001600160a01b038a16600090815260016020526040812090610486610726565b6001600160a01b031681526020810191909152604001600020549190610971565b61072a565b5060019392505050565b60055460ff1690565b60006104206104cc610726565b846104a785600160006104dd610726565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490610a08565b60055460009061010090046001600160a01b03163314610574576040805162461bcd60e51b815260206004820152601a60248201527f4c6f73736c6573735632546f6b656e3a20464f5242494444454e000000000000604482015290519081900360640190fd5b6104208383610a69565b6001600160a01b031660009081526020819052604090205490565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104025780601f106103d757610100808354040283529160200191610402565b60055460009061010090046001600160a01b03163314610661576040805162461bcd60e51b815260206004820152601a60248201527f4c6f73736c6573735632546f6b656e3a20464f5242494444454e000000000000604482015290519081900360640190fd5b6104208383610b59565b6000610420610678610726565b846104a785604051806060016040528060258152602001610dd760259139600160006106a2610726565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190610971565b60006104206106e0610726565b8484610816565b60055461010090046001600160a01b031681565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b3390565b6001600160a01b03831661076f5760405162461bcd60e51b8152600401808060200182810382526024815260200180610db36024913960400191505060405180910390fd5b6001600160a01b0382166107b45760405162461bcd60e51b8152600401808060200182810382526022815260200180610cfd6022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b03831661085b5760405162461bcd60e51b8152600401808060200182810382526025815260200180610d8e6025913960400191505060405180910390fd5b6001600160a01b0382166108a05760405162461bcd60e51b8152600401808060200182810382526023815260200180610cb86023913960400191505060405180910390fd5b6108ab838383610c55565b6108e881604051806060016040528060268152602001610d1f602691396001600160a01b0386166000908152602081905260409020549190610971565b6001600160a01b0380851660009081526020819052604080822093909355908416815220546109179082610a08565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115610a005760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109c55781810151838201526020016109ad565b50505050905090810190601f1680156109f25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600082820183811015610a62576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001600160a01b038216610ac4576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b610ad060008383610c55565b600254610add9082610a08565b6002556001600160a01b038216600090815260208190526040902054610b039082610a08565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038216610b9e5760405162461bcd60e51b8152600401808060200182810382526021815260200180610d6d6021913960400191505060405180910390fd5b610baa82600083610c55565b610be781604051806060016040528060228152602001610cdb602291396001600160a01b0385166000908152602081905260409020549190610971565b6001600160a01b038316600090815260208190526040902055600254610c0d9082610c5a565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b505050565b600082821115610cb1576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220c510d96b1e7590f4ed917cc16ea5d43c52ab25325ed1f7430d41a5b2456a4a3764736f6c634300060c00334c6f73736c6573735632546f6b656e3a2073657420706f6f6c20746f20746865207a65726f20616464726573734c6f73736c6573735632466163746f72793a20464f5242494444454e000000004c6f73736c6573735632466163746f72793a2073657420666565546f20746f20746865207a65726f20616464726573734c6f73736c6573735632466163746f72793a20544f4b454e204e414d4520494e50555420495320494e56414c49444c6f73736c6573735632466163746f72793a204944454e544943414c5f4144445245535345534c6f73736c6573735632466163746f72793a2066656550657263656e74206d757374206265206c657373207468616e20505245434953494f4e4c6f73736c6573735632466163746f72793a20736574205f70656e64696e6744414f20746f20746865207a65726f20616464726573734c6f73736c6573735632466163746f72793a20504f4f4c204d555354204245204143544956454c6f73736c6573735632466163746f72793a20736574205f44414f20746f20746865207a65726f20616464726573734c6f73736c6573735632466163746f72793a2041474752454741544f52205a45524f5f414444524553534c6f73736c6573735632466163746f72793a2042494444494e47204455524154494f4e20494e56414c49445f414d4f554e544c6f73736c6573735632466163746f72793a20544f4b454e2053594d424f4c20494e50555420495320494e56414c49444c6f73736c6573735632466163746f72793a20414444524553532050524f5649444552205a45524f5f414444524553534c6f73736c6573735632466163746f72793a2047414d494e47204455524154494f4e20494e56414c49445f414d4f554e54a2646970667358221220e93527757657f498e5582ebe25f1d8d5dace4f5c16e643a75899b0d770245ee964736f6c634300060c00334c6f73736c6573735632466163746f72793a207365742044414f20746865207a65726f2061646472657373000000000000000000000000fd9656df3e4dca84c260137aecba416050aea145
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000fd9656df3e4dca84c260137aecba416050aea145
-----Decoded View---------------
Arg [0] : _DAO (address): 0xfd9656df3e4dca84c260137aecba416050aea145
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000fd9656df3e4dca84c260137aecba416050aea145
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|