More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
PawnShop
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.23; // use copies of openzeppelin contracts with changed names for avoid dependency issues import "../interfaces/IERC20.sol"; import "../interfaces/IERC721.sol"; import "../interfaces/IPawnShop.sol"; import "../lib/AppLib.sol"; import "../openzeppelin/ERC721Holder.sol"; import "../openzeppelin/ReentrancyGuard.sol"; import "../relay/ERC2771Context.sol"; interface IDelegation { function clearDelegate(bytes32 _id) external; function setDelegate(bytes32 _id, address _delegate) external; } /// @title PawnShop.sol contract provides a useful and flexible solution for borrowing /// and lending assets with a unique feature of supporting both ERC721 and ERC20 tokens as collateral. /// The contract's modular design allows for easy customization of fees, waiting periods, /// and other parameters, providing a solid foundation for a decentralized borrowing and lending platform. /// @author belbix contract PawnShop is ERC721Holder, ReentrancyGuard, IPawnShop, ERC2771Context { //region ------------------------ Constants /// @notice Version of the contract /// @dev Should be incremented when contract changed string public constant VERSION = "1.0.10"; /// @dev Time lock for any governance actions uint constant public TIME_LOCK = 2 days; /// @dev Denominator for any internal computation with low precision uint constant public DENOMINATOR = 10000; /// @dev Governance can't set fee more than this value uint constant public PLATFORM_FEE_MAX = 1000; // 10% /// @dev Standard auction duration that refresh when a new bid placed uint constant public AUCTION_DURATION = 1 days; /// @dev Timestamp date when contract created uint public immutable createdTs; /// @dev Block number when contract created uint public immutable createdBlock; //endregion ------------------------ Constants //region ------------------------ Changeable variables /// @dev Contract owner. Should be a multi-signature wallet. address public owner; /// @dev Fee recipient. Assume it will be a place with ability to manage different tokens address public feeRecipient; /// @dev 10% by default, percent of acquired tokens that will be used for buybacks uint public platformFee = 1000; /// @dev Amount of tokens for open position. Protection against spam uint public positionDepositAmount; /// @dev Token for antispam protection. Zero address means no protection address public positionDepositToken; /// @dev Time-locks for governance actions mapping(GovernanceAction => TimeLock) public timeLocks; //endregion ------------------------ Changeable variables //region ------------------------ Positions /// @inheritdoc IPawnShop uint public override positionCounter = 1; /// @dev PosId => Position. Hold all positions. Any record should not be removed mapping(uint => Position) public positions; /// @inheritdoc IPawnShop uint[] public override openPositions; /// @inheritdoc IPawnShop mapping(address => uint[]) public override positionsByCollateral; /// @inheritdoc IPawnShop mapping(address => uint[]) public override positionsByAcquired; /// @inheritdoc IPawnShop mapping(address => uint[]) public override borrowerPositions; /// @inheritdoc IPawnShop mapping(address => uint[]) public override lenderPositions; /// @inheritdoc IPawnShop mapping(IndexType => mapping(uint => uint)) public override posIndexes; //endregion ------------------------ Positions //region ------------------------ Auction /// @inheritdoc IPawnShop uint public override auctionBidCounter = 1; /// @dev BidId => Bid. Hold all bids. Any record should not be removed mapping(uint => AuctionBid) public auctionBids; /// @inheritdoc IPawnShop mapping(address => mapping(uint => uint)) public override lenderOpenBids; /// @inheritdoc IPawnShop mapping(uint => uint[]) public override positionToBidIds; /// @inheritdoc IPawnShop mapping(uint => uint) public override lastAuctionBidTs; //endregion ------------------------ Auction //region ------------------------ Constructor constructor( address _owner, address _depositToken, uint _positionDepositAmount, address _feeRecipient ) { if (_owner == address(0)) revert IAppErrors.PawnShopZeroOwner(); if (_feeRecipient == address(0)) revert IAppErrors.PawnShopZeroFeeRecipient(); owner = _owner; feeRecipient = _feeRecipient; positionDepositToken = _depositToken; createdTs = block.timestamp; createdBlock = block.number; positionDepositAmount = _positionDepositAmount; } //endregion ------------------------ Constructor //region ------------------------ Restrictions modifier onlyOwner() { if (_msgSender() != owner) revert IAppErrors.PawnShopNotOwner(); _; } /// @dev Check time lock for governance actions and revert if conditions wrong modifier checkTimeLock(GovernanceAction action, address _address, uint _uint){ TimeLock memory timeLock = timeLocks[action]; if (timeLock.time == 0 || timeLock.time >= block.timestamp) revert IAppErrors.PawnShopTimeLock(); if (_address != address(0)) { if (timeLock.addressValue != _address) revert IAppErrors.PawnShopWrongAddressValue(); } if (_uint != 0) { if (timeLock.uintValue != _uint) revert IAppErrors.PawnShopWrongUintValue(); } _; delete timeLocks[action]; } //endregion ------------------------ Restrictions //region ------------------------ User actions /// @inheritdoc IPawnShop function openPosition( address _collateralToken, uint _collateralAmount, uint _collateralTokenId, address _acquiredToken, uint _acquiredAmount, uint _posDurationBlocks, uint _posFee, uint minAuctionAmount ) external nonReentrant override returns (uint){ if (_posFee > DENOMINATOR * 10) revert IAppErrors.PawnShopPosFeeAbsurdlyHigh(); if (_posDurationBlocks == 0 && _posFee != 0) revert IAppErrors.PawnShopPosFeeForInstantDealForbidden(); if (_collateralAmount == 0 && _collateralTokenId == 0) revert IAppErrors.PawnShopWrongAmounts(); if (_collateralToken == address(0)) revert IAppErrors.PawnShopZeroCToken(); if (_acquiredToken == address(0)) revert IAppErrors.PawnShopZeroAToken(); AssetType assetType = _getAssetType(_collateralToken); if ( (!(assetType == AssetType.ERC20 && _collateralAmount != 0 && _collateralTokenId == 0)) && (!(assetType == AssetType.ERC721 && _collateralAmount == 0 && _collateralTokenId != 0)) ) revert IAppErrors.PawnShopIncorrect(); Position memory pos; { PositionInfo memory info = PositionInfo( _posDurationBlocks, _posFee, block.number, block.timestamp ); PositionCollateral memory collateral = PositionCollateral( _collateralToken, assetType, _collateralAmount, _collateralTokenId ); PositionAcquired memory acquired = PositionAcquired( _acquiredToken, _acquiredAmount ); PositionExecution memory execution = PositionExecution( address(0), 0, 0, 0 ); pos = Position( positionCounter, // id _msgSender(), // borrower positionDepositToken, positionDepositAmount, true, // open minAuctionAmount, info, collateral, acquired, execution ); } openPositions.push(pos.id); posIndexes[IndexType.LIST][pos.id] = openPositions.length - 1; positionsByCollateral[_collateralToken].push(pos.id); posIndexes[IndexType.BY_COLLATERAL][pos.id] = positionsByCollateral[_collateralToken].length - 1; positionsByAcquired[_acquiredToken].push(pos.id); posIndexes[IndexType.BY_ACQUIRED][pos.id] = positionsByAcquired[_acquiredToken].length - 1; borrowerPositions[_msgSender()].push(pos.id); posIndexes[IndexType.BORROWER_POSITION][pos.id] = borrowerPositions[_msgSender()].length - 1; positions[pos.id] = pos; positionCounter++; _takeDeposit(pos.id); _transferCollateral(pos.collateral, _msgSender(), address(this)); emit PositionOpened( _msgSender(), pos.id, _collateralToken, _collateralAmount, _collateralTokenId, _acquiredToken, _acquiredAmount, _posDurationBlocks, _posFee ); return pos.id; } /// @inheritdoc IPawnShop function closePosition(uint id) external nonReentrant override { Position storage pos = positions[id]; if (pos.id != id) revert IAppErrors.PawnShopWrongId(); if (pos.borrower != _msgSender()) revert IAppErrors.PawnShopNotBorrower(); if (pos.execution.lender != address(0)) revert IAppErrors.PawnShopPositionExecuted(); if (!pos.open) revert IAppErrors.PawnShopPositionClosed(); _removePosFromIndexes(pos); removeIndexed(borrowerPositions[pos.borrower], posIndexes[IndexType.BORROWER_POSITION], pos.id); _transferCollateral(pos.collateral, address(this), pos.borrower); _returnDeposit(id); pos.open = false; emit PositionClosed(_msgSender(), id); } /// @inheritdoc IPawnShop function bid(uint id, uint amount) external nonReentrant override { Position storage pos = positions[id]; if (pos.id != id) revert IAppErrors.PawnShopWrongId(); if (!pos.open) revert IAppErrors.PawnShopPositionClosed(); if (pos.execution.lender != address(0)) revert IAppErrors.PawnShopPositionExecuted(); if (pos.acquired.acquiredAmount != 0) { if (amount != pos.acquired.acquiredAmount) revert IAppErrors.PawnShopWrongBidAmount(); _executeBid(pos, 0, amount, _msgSender(), _msgSender()); } else { _auctionBid(pos, amount, _msgSender()); } } /// @inheritdoc IPawnShop function claim(uint id) external nonReentrant override { Position storage pos = positions[id]; if (pos.id != id) revert IAppErrors.PawnShopWrongId(); if (pos.execution.lender != _msgSender()) revert IAppErrors.PawnShopNotLender(); uint posEnd = pos.execution.posStartBlock + pos.info.posDurationBlocks; if (posEnd >= block.number) revert IAppErrors.PawnShopTooEarlyToClaim(); if (!pos.open) revert IAppErrors.PawnShopPositionClosed(); _endPosition(pos); _transferCollateral(pos.collateral, address(this), _msgSender()); _returnDeposit(id); emit PositionClaimed(_msgSender(), id); } /// @inheritdoc IPawnShop function redeem(uint id) external nonReentrant override { Position storage pos = positions[id]; if (pos.id != id) revert IAppErrors.PawnShopWrongId(); if (pos.borrower != _msgSender()) revert IAppErrors.PawnShopNotBorrower(); if (pos.execution.lender == address(0)) revert IAppErrors.PawnShopPositionNotExecuted(); if (!pos.open) revert IAppErrors.PawnShopPositionClosed(); _endPosition(pos); uint toSend = _toRedeem(id); IERC20(pos.acquired.acquiredToken).transferFrom(_msgSender(), pos.execution.lender, toSend); _transferCollateral(pos.collateral, address(this), _msgSender()); _returnDeposit(id); emit PositionRedeemed(_msgSender(), id); } /// @inheritdoc IPawnShop function acceptAuctionBid(uint posId) external nonReentrant override { if (lastAuctionBidTs[posId] + AUCTION_DURATION >= block.timestamp) revert IAppErrors.PawnShopAuctionNotEnded(); if (positionToBidIds[posId].length == 0) revert IAppErrors.PawnShopNoBids(); uint bidId = positionToBidIds[posId][positionToBidIds[posId].length - 1]; AuctionBid storage _bid = auctionBids[bidId]; if (_bid.id == 0) revert IAppErrors.PawnShopAuctionBidNotFound(); if (!_bid.open) revert IAppErrors.PawnShopBidClosed(); if (_bid.posId != posId) revert IAppErrors.PawnShopWrongBid(); Position storage pos = positions[posId]; if (pos.borrower != _msgSender()) revert IAppErrors.PawnShopNotBorrower(); if (!pos.open) revert IAppErrors.PawnShopPositionClosed(); pos.acquired.acquiredAmount = _bid.amount; _executeBid(pos, bidId, _bid.amount, address(this), _bid.lender); lenderOpenBids[_bid.lender][pos.id] = 0; _bid.open = false; emit AuctionBidAccepted(_msgSender(), posId, _bid.id); } /// @inheritdoc IPawnShop function closeAuctionBid(uint bidId) external nonReentrant override { AuctionBid storage _bid = auctionBids[bidId]; address lender = _bid.lender; if (_bid.id == 0) revert IAppErrors.PawnShopBidNotFound(); if (!_bid.open) revert IAppErrors.PawnShopBidClosed(); if (lender != _msgSender()) revert IAppErrors.PawnShopNotLender(); Position storage pos = positions[_bid.posId]; uint _lastAuctionBidTs = lastAuctionBidTs[pos.id]; bool isAuctionEnded = _lastAuctionBidTs + AUCTION_DURATION < block.timestamp; // in case if auction is not accepted during 2 weeks lender can close the bid bool isAuctionOverdue = _lastAuctionBidTs + AUCTION_DURATION + 2 weeks < block.timestamp; bool isLastBid = false; if (positionToBidIds[pos.id].length != 0) { uint lastBidId = positionToBidIds[pos.id][positionToBidIds[pos.id].length - 1]; isLastBid = lastBidId == bidId; } if (!((isLastBid && isAuctionEnded) || !isLastBid || !pos.open || isAuctionOverdue)) revert IAppErrors.PawnShopAuctionNotEnded(); lenderOpenBids[lender][pos.id] = 0; _bid.open = false; IERC20(pos.acquired.acquiredToken).transfer(lender, _bid.amount); emit AuctionBidClosed(pos.id, bidId); } //endregion ------------------------ User actions //region ------------------------ Internal functions /// @dev Transfer to this contract a deposit function _takeDeposit(uint posId) internal { Position storage pos = positions[posId]; if (pos.depositToken != address(0)) { IERC20(pos.depositToken).transferFrom(pos.borrower, address(this), pos.depositAmount); } } /// @dev Return to borrower a deposit function _returnDeposit(uint posId) internal { Position storage pos = positions[posId]; if (pos.depositToken != address(0)) { IERC20(pos.depositToken).transfer(pos.borrower, pos.depositAmount); } } /// @dev Execute bid for the open position /// Transfer acquired tokens to borrower /// In case of instant deal transfer collateral to lender function _executeBid( Position storage pos, uint bidId, uint amount, address acquiredMoneyHolder, address lender ) internal { uint feeAmount = amount * platformFee / DENOMINATOR; uint toSend = amount - feeAmount; if (acquiredMoneyHolder == address(this)) { IERC20(pos.acquired.acquiredToken).transfer(pos.borrower, toSend); } else { IERC20(pos.acquired.acquiredToken).transferFrom(acquiredMoneyHolder, pos.borrower, toSend); IERC20(pos.acquired.acquiredToken).transferFrom(acquiredMoneyHolder, address(this), feeAmount); } _transferFee(pos.acquired.acquiredToken, feeAmount); pos.execution.lender = lender; pos.execution.posStartBlock = block.number; pos.execution.posStartTs = block.timestamp; _removePosFromIndexes(pos); lenderPositions[lender].push(pos.id); posIndexes[IndexType.LENDER_POSITION][pos.id] = lenderPositions[lender].length - 1; // instant buy if (pos.info.posDurationBlocks == 0) { _transferCollateral(pos.collateral, address(this), lender); _returnDeposit(pos.id); // fix for SCB-1029 _endPosition(pos); } emit BidExecuted(pos.id, bidId, amount, acquiredMoneyHolder, lender); } /// @dev Open an auction bid /// Transfer acquired token to this contract function _auctionBid(Position storage pos, uint amount, address lender) internal { if (lenderOpenBids[lender][pos.id] != 0) revert IAppErrors.PawnShopBidAlreadyExists(); if (amount < pos.minAuctionAmount) revert IAppErrors.PawnShopTooLowBid(); if (positionToBidIds[pos.id].length != 0) { // if we have bids need to check auction duration if (lastAuctionBidTs[pos.id] + AUCTION_DURATION <= block.timestamp) revert IAppErrors.PawnShopAuctionEnded(); uint lastBidId = positionToBidIds[pos.id][positionToBidIds[pos.id].length - 1]; AuctionBid storage lastBid = auctionBids[lastBidId]; if (lastBid.amount * 110 / 100 >= amount) revert IAppErrors.PawnShopNewBidTooLow(); } AuctionBid memory _bid = AuctionBid( auctionBidCounter, pos.id, lender, amount, true ); positionToBidIds[pos.id].push(_bid.id); // write index + 1 for keep zero as empty value lenderOpenBids[lender][pos.id] = positionToBidIds[pos.id].length; IERC20(pos.acquired.acquiredToken).transferFrom(_msgSender(), address(this), amount); lastAuctionBidTs[pos.id] = block.timestamp; auctionBids[_bid.id] = _bid; auctionBidCounter++; emit AuctionBidOpened(pos.id, _bid.id, amount, lender); } /// @dev Finalize position. Remove position from indexes function _endPosition(Position storage pos) internal { if (pos.execution.posEndTs != 0) revert IAppErrors.PawnShopAlreadyClaimed(); pos.open = false; pos.execution.posEndTs = block.timestamp; removeIndexed(borrowerPositions[pos.borrower], posIndexes[IndexType.BORROWER_POSITION], pos.id); if (pos.execution.lender != address(0)) { removeIndexed(lenderPositions[pos.execution.lender], posIndexes[IndexType.LENDER_POSITION], pos.id); } } /// @dev Transfer collateral from sender to recipient function _transferCollateral(PositionCollateral memory _collateral, address _sender, address _recipient) internal { if (_collateral.collateralType == AssetType.ERC20) { if (_sender == address(this)) { IERC20(_collateral.collateralToken).transfer(_recipient, _collateral.collateralAmount); } else { IERC20(_collateral.collateralToken).transferFrom(_sender, _recipient, _collateral.collateralAmount); } } else if (_collateral.collateralType == AssetType.ERC721) { IERC721(_collateral.collateralToken).transferFrom(_sender, _recipient, _collateral.collateralTokenId); } else { revert("TPS: Wrong asset type"); } } /// @dev Transfer fee to platform. Assume that token inside this contract /// Do buyback if possible, otherwise just send to controller for manual handling function _transferFee(address token, uint amount) internal { // little deals can have zero fees if (amount == 0) { return; } IERC20(token).transfer(feeRecipient, amount); } /// @dev Remove position from common indexes function _removePosFromIndexes(Position memory _pos) internal { removeIndexed(openPositions, posIndexes[IndexType.LIST], _pos.id); removeIndexed(positionsByCollateral[_pos.collateral.collateralToken], posIndexes[IndexType.BY_COLLATERAL], _pos.id); removeIndexed(positionsByAcquired[_pos.acquired.acquiredToken], posIndexes[IndexType.BY_ACQUIRED], _pos.id); } //endregion ------------------------ Internal functions //region ------------------------ Views /// @inheritdoc IPawnShop function toRedeem(uint id) external view override returns (uint){ return _toRedeem(id); } function _toRedeem(uint id) private view returns (uint){ Position memory pos = positions[id]; return pos.acquired.acquiredAmount + (pos.acquired.acquiredAmount * pos.info.posFee / DENOMINATOR); } /// @inheritdoc IPawnShop function getAssetType(address _token) external view override returns (AssetType){ return _getAssetType(_token); } function _getAssetType(address _token) private view returns (AssetType){ if (_isERC721(_token)) { return AssetType.ERC721; } else if (_isERC20(_token)) { return AssetType.ERC20; } else { revert("TPS: Unknown asset"); } } /// @dev Return true if given token is ERC721 token function isERC721(address _token) external view override returns (bool) { return _isERC721(_token); } //noinspection NoReturn function _isERC721(address _token) private view returns (bool) { //slither-disable-next-line unused-return,variable-scope,uninitialized-local try IERC721(_token).supportsInterface{gas: 30000}(type(IERC721).interfaceId) returns (bool result){ return result; } catch { return false; } } /// @dev Return true if given token is ERC20 token function isERC20(address _token) external view override returns (bool) { return _isERC20(_token); } //noinspection NoReturn function _isERC20(address _token) private view returns (bool) { //slither-disable-next-line unused-return,variable-scope,uninitialized-local try IERC20(_token).totalSupply{gas: 30000}() returns (uint){ return true; } catch { return false; } } /// @inheritdoc IPawnShop function openPositionsSize() external view override returns (uint) { return openPositions.length; } /// @inheritdoc IPawnShop function auctionBidSize(uint posId) external view override returns (uint) { return positionToBidIds[posId].length; } function positionsByCollateralSize(address collateral) external view override returns (uint) { return positionsByCollateral[collateral].length; } function positionsByAcquiredSize(address acquiredToken) external view override returns (uint) { return positionsByAcquired[acquiredToken].length; } function borrowerPositionsSize(address borrower) external view override returns (uint) { return borrowerPositions[borrower].length; } function lenderPositionsSize(address lender) external view override returns (uint) { return lenderPositions[lender].length; } /// @inheritdoc IPawnShop function getPosition(uint posId) external view override returns (Position memory) { return positions[posId]; } /// @inheritdoc IPawnShop function getAuctionBid(uint bidId) external view override returns (AuctionBid memory) { return auctionBids[bidId]; } //endregion ------------------------ Views //region ------------------------ Governance actions /// @inheritdoc IPawnShop function announceGovernanceAction( GovernanceAction id, address addressValue, uint uintValue ) external onlyOwner override { if (timeLocks[id].time != 0) revert IAppErrors.PawnShopAlreadyAnnounced(); timeLocks[id] = TimeLock( block.timestamp + TIME_LOCK, addressValue, uintValue ); emit GovernanceActionAnnounced(uint(id), addressValue, uintValue); } /// @inheritdoc IPawnShop function setOwner(address _newOwner) external onlyOwner override checkTimeLock(GovernanceAction.ChangeOwner, _newOwner, 0) { if (_newOwner == address(0)) revert IAppErrors.PawnShopZeroAddress(); emit OwnerChanged(owner, _newOwner); owner = _newOwner; } /// @inheritdoc IPawnShop function setFeeRecipient(address _newFeeRecipient) external onlyOwner override checkTimeLock(GovernanceAction.ChangeFeeRecipient, _newFeeRecipient, 0) { if (_newFeeRecipient == address(0)) revert IAppErrors.PawnShopZeroAddress(); emit FeeRecipientChanged(feeRecipient, _newFeeRecipient); feeRecipient = _newFeeRecipient; } /// @inheritdoc IPawnShop function setPlatformFee(uint _value) external onlyOwner override checkTimeLock(GovernanceAction.ChangePlatformFee, address(0), _value) { if (_value > PLATFORM_FEE_MAX) revert IAppErrors.PawnShopTooHighValue(); emit PlatformFeeChanged(platformFee, _value); platformFee = _value; } /// @inheritdoc IPawnShop function setPositionDepositAmount(uint _value) external onlyOwner override checkTimeLock(GovernanceAction.ChangePositionDepositAmount, address(0), _value) { emit DepositAmountChanged(positionDepositAmount, _value); positionDepositAmount = _value; } /// @inheritdoc IPawnShop function setPositionDepositToken(address _value) external onlyOwner override checkTimeLock(GovernanceAction.ChangePositionDepositToken, _value, 0) { emit DepositTokenChanged(positionDepositToken, _value); positionDepositToken = _value; } /// @dev Delegate snapshot votes to another address function delegateVotes(address _delegateContract,bytes32 _id, address _delegate) external onlyOwner { IDelegation(_delegateContract).setDelegate(_id, _delegate); } /// @dev Remove delegated votes. function clearDelegatedVotes(address _delegateContract, bytes32 _id) external onlyOwner { IDelegation(_delegateContract).clearDelegate(_id); } //endregion ------------------------ Governance actions //region ------------------------ ArrayLib /// @dev Remove from array the item with given id and move the last item on it place /// Use with mapping for keeping indexes in correct ordering function removeIndexed( uint256[] storage array, mapping(uint256 => uint256) storage indexes, uint256 id ) internal { AppLib.removeIndexed(array, indexes, id); } //endregion ------------------------ ArrayLib }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.23; /// @notice All errors of the app interface IAppErrors { //region ERC20Errors /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); //endregion ERC20Errors //region ERC721Errors /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); //endregion ERC721Errors error ZeroAddress(); error ZeroValueNotAllowed(); error ZeroToken(); error LengthsMismatch(); error NotEnoughBalance(); error NotEnoughAllowance(); error EmptyNameNotAllowed(); error NotInitialized(); error AlreadyInitialized(); error ReentrancyGuardReentrantCall(); error TooLongString(); error AlreadyDeployed(address deployed); //region Restrictions error ErrorNotDeployer(address sender); error ErrorNotGoc(); error NotGovernance(address sender); error ErrorOnlyEoa(); error NotEOA(address sender); error ErrorForbidden(address sender); error AdminOnly(); error ErrorNotItemController(address sender); error ErrorNotHeroController(address sender); error ErrorNotDungeonFactory(address sender); error ErrorNotObjectController(address sender); error ErrorNotStoryController(); error ErrorNotAllowedSender(); error MintNotAllowed(); //endregion Restrictions //region PackingLib error TooHighValue(uint value); error IntValueOutOfRange(int value); error OutOfBounds(uint index, uint length); error UnexpectedValue(uint expected, uint actual); error WrongValue(uint newValue, uint actual); error IntOutOfRange(int value); error ZeroValue(); /// @notice packCustomDataChange requires an input string with two zero bytes at the beginning /// 0xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0000 /// This error happens if these bytes are not zero error IncompatibleInputString(); error IncorrectOtherItemTypeKind(uint8 kind); //endregion PackingLib //region Hero error ErrorHeroIsNotRegistered(address heroToken); error ErrorHeroIsDead(address heroToken, uint heroTokenId); error ErrorHeroNotInDungeon(); error HeroInDungeon(); error ErrorNotOwner(address token, uint tokenId); error Staked(address heroToken, uint heroId); error NameTaken(); error TooBigName(); error WrongSymbolsInTheName(); error NoPayToken(address token, uint payTokenAmount); error AlreadyHaveReinforcement(); /// @notice SIP-001 - Reinforcement requires 3 skills error ErrorReinforcementRequiresThreeSkills(); error WrongTier(uint tier); error NotEnoughNgLevel(uint8 ngLevel); error NgpNotActive(address hero); error RebornNotAllowed(); error AlreadyPrePaidHero(); //endregion Hero //region Dungeon error ErrorDungeonIsFreeAlready(); error ErrorNoEligibleDungeons(); error ErrorDungeonBusy(); error ErrorNoDungeonsForBiome(uint8 heroBiome); error ErrorDungeonCompleted(); error ErrorAlreadyInDungeon(); error NotEnoughTokens(uint balance, uint expectedBalance); error DungeonAlreadySpecific(uint16 dungNum); error DungeonAlreadySpecific2(uint16 dungNum); error WrongSpecificDungeon(); //endregion Dungeon //region Items error ErrorItemNotEligibleForTheSlot(uint itemType, uint8 itemSlot); error ErrorItemSlotBusyHand(uint8 slot); error ErrorItemSlotBusy(); error ErrorItemNotInSlot(); error ErrorConsumableItemIsUsed(address item); error ErrorCannotRemoveItemFromMap(); error ErrorCannotRemoveDataFromMap(); error EquippedItemsExist(); error ItemEquipped(address item, uint itemId); error ZeroItemMetaType(); error NotZeroOtherItemMetaType(); error ZeroLevel(); error ItemTypeChanged(); error ItemMetaTypeChanged(); error UnknownItem(address item); error ErrorEquipForbidden(); error EquipForbiddenInDungeon(); error TakeOffForbiddenInDungeon(); error Consumable(address item); error NotConsumable(address item); error Broken(address item); error ZeroLife(); error RequirementsToItemAttributes(); error NotEquipped(address item); error ZeroDurability(); error ZeroAugmentation(); error TooHighAgLevel(uint8 augmentationLevel); error UseForbiddenZeroPayToken(); error IncorrectMinMaxAttributeRange(int32 min, int32 max); error SameIdsNotAllowed(); error ZeroFragility(); error OtherTypeItemNotRepairable(); error NotOther(); error DoubleItemUsageForbidden(uint itemIndex, address[] items); error ItemAlreadyUsedInSlot(address item, uint8 equippedSlot); error WrongWayToRegisterItem(); error UnionItemNotFound(address item); error WrongListUnionItemTokens(address item, uint countTokens, uint requiredCountTokens); error UnknownUnionConfig(uint unionConfigId); error UserHasNoKeyPass(address user, address keyPassItem); error MaxValue(uint value); error UnexpectedOtherItem(address item); error NotExist(); //endregion Items //region Stages error ErrorWrongStage(uint stage); error ErrorNotStages(); //endregion Stages //region Level error ErrorWrongLevel(uint heroLevel); error ErrorLevelTooLow(uint heroLevel); error ErrorHeroLevelStartFrom1(); error ErrorWrongLevelUpSum(); error ErrorMaxLevel(); //endregion Level //region Treasure error ErrorNotValidTreasureToken(address treasureToken); //endregion Treasure //region State error ErrorPaused(); error ErrorNotReady(); error ErrorNotObject1(); error ErrorNotObject2(); error ErrorNotCompleted(); //endregion State //region Biome error ErrorNotBiome(); error ErrorIncorrectBiome(uint biome); error TooHighBiome(uint biome); //endregion Biome //region Misc error ErrorWrongMultiplier(uint multiplier); error ErrorNotEnoughMana(uint32 mana, uint requiredMana); error ErrorExperienceMustNotDecrease(); error ErrorNotEnoughExperience(); error ErrorNotChances(); error ErrorNotEligible(address heroToken, uint16 dungNum); error ErrorZeroKarmaNotAllowed(); //endregion Misc //region GOC error GenObjectIdBiomeOverflow(uint8 biome); error GenObjectIdSubTypeOverflow(uint subType); error GenObjectIdIdOverflow(uint id); error UnknownObjectTypeGoc1(uint8 objectType); error UnknownObjectTypeGoc2(uint8 objectType); error UnknownObjectTypeGocLib1(uint8 objectType); error UnknownObjectTypeGocLib2(uint8 objectType); error UnknownObjectTypeForSubtype(uint8 objectSubType); error FightDelay(); error ZeroChance(); error TooHighChance(uint32 chance); error TooHighRandom(uint random); error EmptyObjects(); error ObjectNotFound(); error WrongGetObjectTypeInput(); error WrongChances(uint32 chances, uint32 maxChances); //endregion GOC //region Story error PageNotRemovedError(uint pageId); error NotItem1(); error NotItem2(); error NotRandom(uint32 random); error NotHeroData(); error NotGlobalData(); error ZeroStoryIdRemoveStory(); error ZeroStoryIdStoryAction(); error ZeroStoryIdAction(); error NotEnoughAmount(uint balance, uint requiredAmount); error NotAnswer(); error AnswerStoryIdMismatch(uint16 storyId, uint16 storyIdFromAnswerHash); error AnswerPageIdMismatch(uint16 pageId, uint16 pageIdFromAnswerHash); //endregion Story //region FightLib error NotMagic(); error NotAType(uint atype); //endregion FightLib //region MonsterLib error NotYourDebuffItem(); error UnknownAttackType(uint attackType); error NotYourAttackItem(); /// @notice The skill item cannot be used because it doesn't belong either to the hero or to the hero's helper error NotYourBuffItem(); //endregion MonsterLib //region GameToken error ApproveToZeroAddress(); error MintToZeroAddress(); error TransferToZeroAddress(); error TransferAmountExceedsBalance(uint balance, uint value); error InsufficientAllowance(); error BurnAmountExceedsBalance(); error NotMinter(address sender); //endregion GameToken //region NFT error TokenTransferNotAllowed(); error IdOverflow(uint id); error NotExistToken(uint tokenId); error EquippedItemIsNotAllowedToTransfer(uint tokenId); //endregion NFT //region CalcLib error TooLowX(uint x); //endregion CalcLib //region Controller error NotFutureGovernance(address sender); //endregion Controller //region Oracle error OracleWrongInput(); //endregion Oracle //region ReinforcementController error AlreadyStaked(); error MaxFee(uint8 fee); error MinFee(uint8 fee); error StakeHeroNotStats(); error NotStaked(); error NoStakedHeroes(); error GuildHelperNotAvailable(uint guildId, address helper, uint helperId); error HelperNotAvailableInGivenBiome(); //endregion ReinforcementController //region SponsoredHero error InvalidHeroClass(); error ZeroAmount(); error InvalidProof(); error NoHeroesAvailable(); error AlreadyRegistered(); //endregion SponsoredHero //region SacraRelay error SacraRelayNotOwner(); error SacraRelayNotDelegator(); error SacraRelayNotOperator(); error SacraRelayInvalidChainId(uint callChainId, uint blockChainId); error SacraRelayInvalidNonce(uint callNonce, uint txNonce); error SacraRelayDeadline(); error SacraRelayDelegationExpired(); error SacraRelayNotAllowed(); error SacraRelayInvalidSignature(); /// @notice This error is generated when custom error is caught /// There is no info about custom error in SacraRelay /// but you can decode custom error by selector, see tests error SacraRelayNoErrorSelector(bytes4 selector, string tracingInfo); /// @notice This error is generated when custom error is caught /// There is no info about custom error in SacraRelay /// but you can decode custom error manually from {errorBytes} as following: /// if (keccak256(abi.encodeWithSignature("MyError()")) == keccak256(errorBytes)) { ... } error SacraRelayUnexpectedReturnData(bytes errorBytes, string tracingInfo); error SacraRelayCallToNotContract(address notContract, string tracingInfo); //endregion SacraRelay //region Misc error UnknownHeroClass(uint heroClass); error AbsDiff(int32 a, int32 b); //region Misc //region ------------------------ UserController error NoAvailableLootBox(address msgSender, uint lootBoxKind); error FameHallHeroAlreadyRegistered(uint8 openedNgLevel); //endregion ------------------------ UserController //region ------------------------ Guilds error AlreadyGuildMember(); error NotGuildMember(); error WrongGuild(); error GuildActionForbidden(uint right); error GuildHasMaxSize(uint guildSize); error GuildHasMaxLevel(uint level); error TooLongUrl(); error TooLongDescription(); error CannotRemoveGuildOwnerFromNotEmptyGuild(); error GuildControllerOnly(); error GuildAlreadyHasShelter(); error ShelterIsBusy(); error ShelterIsNotRegistered(); error ShelterIsNotOwnedByTheGuild(); error ShelterIsInUse(); error GuildHasNoShelter(); error ShelterBidIsNotAllowedToBeUsed(); error ShelterHasHeroesInside(); error SecondGuildAdminIsNotAllowed(); error NotEnoughGuildBankBalance(uint guildId); error GuildReinforcementCooldownPeriod(); error NoStakedGuildHeroes(); error NotStakedInGuild(); error ShelterHasNotEnoughLevelForReinforcement(); error NotBusyGuildHelper(); error GuildRequestNotActive(); error GuildRequestNotAvailable(); error NotAdminCannotAddMemberWithNotZeroRights(); //endregion ------------------------ Guilds //region ------------------------ Shelters error ErrorNotShelterController(); error ErrorNotGuildController(); error ShelterHasNotItem(uint shelterId, address item); error MaxNumberItemsSoldToday(uint numSoldItems, uint limit); error GuildHasNotEnoughPvpPoints(uint64 pointsAvailable, uint pointRequired); error FreeShelterItemsAreNotAllowed(uint shelterId, address item); error TooLowShelterLevel(uint8 shelterLevel, uint8 allowedShelterLevel); error NotEnoughPvpPointsCapacity(address user, uint usedPoints, uint pricePvpPoints, uint64 capactiy); error IncorrectShelterLevel(uint8 shelterLevel); //endregion ------------------------ Shelters //region ------------------------ Auction error WrongAuctionPosition(); error AuctionPositionClosed(); error AuctionBidOpened(uint positionId); error TooLowAmountToBid(); error AuctionEnded(); error TooLowAmountForNewBid(); error AuctionSellerOnly(); error AuctionBuyerOnly(); error AuctionBidNotFound(); error AuctionBidClosed(); error OnlyShelterAuction(); error CannotCloseLastBid(); error AuctionNotEnded(); error NotShelterAuction(); error AuctionPositionOpened(uint positionId); error AuctionSellerCannotBid(); error CannotApplyNotLastBid(); error AuctionGuildWithShelterCannotBid(); //endregion ------------------------ Auction //region ------------------------ Pawnshop error AuctionPositionNotSupported(uint positionId); error PositionNotSupported(uint positionId); error NotNftPositionNotSupported(uint positionId); error CallFailed(bytes callResultData); error PawnShopZeroOwner(); error PawnShopZeroFeeRecipient(); error PawnShopNotOwner(); error PawnShopAlreadyAnnounced(); error PawnShopTimeLock(); error PawnShopWrongAddressValue(); error PawnShopWrongUintValue(); error PawnShopZeroAddress(); error PawnShopTooHighValue(); error PawnShopZeroAToken(); error PawnShopZeroCToken(); error PawnShopWrongAmounts(); error PawnShopPosFeeForInstantDealForbidden(); error PawnShopPosFeeAbsurdlyHigh(); error PawnShopIncorrect(); error PawnShopWrongId(); error PawnShopNotBorrower(); error PawnShopPositionClosed(); error PawnShopPositionExecuted(); error PawnShopWrongBidAmount(); error PawnShopTooLowBid(); error PawnShopNewBidTooLow(); error PawnShopBidAlreadyExists(); error PawnShopAuctionEnded(); error PawnShopNotLender(); error PawnShopTooEarlyToClaim(); error PawnShopPositionNotExecuted(); error PawnShopAlreadyClaimed(); error PawnShopAuctionNotEnded(); error PawnShopBidClosed(); error PawnShopNoBids(); error PawnShopAuctionBidNotFound(); error PawnShopWrongBid(); error PawnShopBidNotFound(); //endregion ------------------------ Pawnshop }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^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.8.0; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.23; /// @title Interface for Tetu PawnShop contract /// @author belbix interface IPawnShop { event PositionOpened( address indexed sender, uint256 posId, address collateralToken, uint256 collateralAmount, uint256 collateralTokenId, address acquiredToken, uint256 acquiredAmount, uint256 posDurationBlocks, uint256 posFee ); event PositionClosed(address indexed borrower, uint256 posId); event BidExecuted( uint256 posId, uint256 bidId, uint256 amount, address acquiredMoneyHolder, address lender ); event AuctionBidOpened(uint256 posId, uint256 bidId, uint256 amount, address lender); event PositionClaimed(address indexed sender, uint256 posId); event PositionRedeemed(address indexed sender, uint256 posId); event AuctionBidAccepted(address indexed borrower, uint256 posId, uint256 bidId); event AuctionBidClosed(uint256 posId, uint256 bidId); event GovernanceActionAnnounced(uint256 id, address addressValue, uint256 uintValue); event OwnerChanged(address oldOwner, address newOwner); event FeeRecipientChanged(address oldRecipient, address newRecipient); event PlatformFeeChanged(uint256 oldFee, uint256 newFee); event DepositAmountChanged(uint256 oldAmount, uint256 newAmount); event DepositTokenChanged(address oldToken, address newToken); enum GovernanceAction { ChangeOwner, // 0 ChangeFeeRecipient, // 1 ChangePlatformFee, // 2 ChangePositionDepositAmount, // 3 ChangePositionDepositToken // 4 } enum AssetType { ERC20, // 0 ERC721 // 1 } enum IndexType { LIST, // 0 BY_COLLATERAL, // 1 BY_ACQUIRED, // 2 BORROWER_POSITION, // 3 LENDER_POSITION // 4 } struct TimeLock { uint256 time; address addressValue; uint256 uintValue; } struct Position { uint256 id; address borrower; address depositToken; uint256 depositAmount; bool open; uint minAuctionAmount; PositionInfo info; PositionCollateral collateral; PositionAcquired acquired; PositionExecution execution; } struct PositionInfo { uint256 posDurationBlocks; uint256 posFee; uint256 createdBlock; uint256 createdTs; } struct PositionCollateral { address collateralToken; AssetType collateralType; uint256 collateralAmount; uint256 collateralTokenId; } struct PositionAcquired { address acquiredToken; uint256 acquiredAmount; } struct PositionExecution { address lender; uint256 posStartBlock; uint256 posStartTs; uint256 posEndTs; } struct AuctionBid { uint256 id; uint256 posId; address lender; uint256 amount; bool open; } // ****************** VIEWS **************************** /// @dev PosId counter. Should start from 1 for keep 0 as empty value function positionCounter() external view returns (uint256); /// @notice Return Position for given id /// @dev AbiEncoder not able to auto generate functions for mapping with structs function getPosition(uint256 posId) external view returns (Position memory); /// @dev Hold open positions ids. Removed when position closed function openPositions(uint256 index) external view returns (uint256 posId); /// @dev Collateral token => PosIds function positionsByCollateral(address collateralToken, uint256 index) external view returns (uint256 posId); /// @dev Acquired token => PosIds function positionsByAcquired(address acquiredToken, uint256 index) external view returns (uint256 posId); /// @dev Borrower token => PosIds function borrowerPositions(address borrower, uint256 index) external view returns (uint256 posId); /// @dev Lender token => PosIds function lenderPositions(address lender, uint256 index) external view returns (uint256 posId); /// @dev index type => PosId => index /// Hold array positions for given type of array function posIndexes(IndexType typeId, uint256 posId) external view returns (uint256 index); /// @dev BidId counter. Should start from 1 for keep 0 as empty value function auctionBidCounter() external view returns (uint256); /// @notice Return auction bid for given id /// @dev AbiEncoder not able to auto generate functions for mapping with structs function getAuctionBid(uint256 bidId) external view returns (AuctionBid memory); /// @dev lender => PosId => positionToBidIds + 1 /// Lender auction position for given PosId. 0 keep for empty position function lenderOpenBids(address lender, uint256 posId) external view returns (uint256 index); /// @dev PosId => bidIds. All open and close bids for the given position function positionToBidIds(uint256 posId, uint256 index) external view returns (uint256 bidId); /// @dev PosId => timestamp. Timestamp of the last bid for the auction function lastAuctionBidTs(uint256 posId) external view returns (uint256 ts); /// @dev Return amount required for redeem position function toRedeem(uint256 posId) external view returns (uint256 amount); /// @dev Return asset type ERC20 or ERC721 function getAssetType(address _token) external view returns (AssetType); function isERC721(address _token) external view returns (bool); function isERC20(address _token) external view returns (bool); /// @dev Return size of active positions function openPositionsSize() external view returns (uint256); /// @dev Return size of all auction bids for given position function auctionBidSize(uint256 posId) external view returns (uint256); function positionsByCollateralSize(address collateral) external view returns (uint256); function positionsByAcquiredSize(address acquiredToken) external view returns (uint256); function borrowerPositionsSize(address borrower) external view returns (uint256); function lenderPositionsSize(address lender) external view returns (uint256); // ************* USER ACTIONS ************* /// @dev Borrower action. Assume approve /// Allows the user to create a new borrowing position by depositing their collateral tokens. function openPosition( address _collateralToken, uint256 _collateralAmount, uint256 _collateralTokenId, address _acquiredToken, uint256 _acquiredAmount, uint256 _posDurationBlocks, uint256 _posFee, uint minAuctionPrice ) external returns (uint256); /// @dev Borrower action /// Close not executed position. Return collateral and deposit to borrower function closePosition(uint256 id) external; /// @dev Lender action. Assume approve for acquired token /// Place a bid for given position ID /// It can be an auction bid if acquired amount is zero function bid(uint256 id, uint256 amount) external; /// @dev Lender action /// Transfer collateral to lender if borrower didn't return the loan /// Deposit will be returned to borrower function claim(uint256 id) external; /// @dev Borrower action. Assume approve on acquired token /// Return the loan to lender, transfer collateral and deposit to borrower function redeem(uint256 id) external; /// @dev Borrower action. Assume that auction ended. /// Transfer acquired token to borrower function acceptAuctionBid(uint256 posId) external; /// @dev Lender action. Requires ended auction, or not the last bid /// Close auction bid and transfer acquired tokens to lender function closeAuctionBid(uint256 bidId) external; /// @dev Announce governance action function announceGovernanceAction(GovernanceAction id, address addressValue, uint256 uintValue) external; /// @dev Set new contract owner function setOwner(address _newOwner) external; /// @dev Set new fee recipient function setFeeRecipient(address _newFeeRecipient) external; /// @dev Platform fee in range 0 - 500, with denominator 10000 function setPlatformFee(uint256 _value) external; /// @dev Tokens amount that need to deposit for a new position /// Will be returned when position closed function setPositionDepositAmount(uint256 _value) external; /// @dev Tokens that need to deposit for a new position function setPositionDepositToken(address _value) external; function platformFee() external view returns (uint); function positionDepositToken() external view returns (address); function AUCTION_DURATION() external view returns (uint); function positionDepositAmount() external view returns (uint); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.23; import "../interfaces/IERC20.sol"; /// @notice Common internal utils library AppLib { /// @notice Make infinite approve of {token} to {spender} if the approved amount is less than {amount} /// @dev Should NOT be used for third-party pools function approveIfNeeded(address token, uint amount, address spender) internal { if (IERC20(token).allowance(address(this), spender) < amount) { IERC20(token).approve(spender, type(uint).max); } } /// @dev Remove from array the item with given id and move the last item on it place /// Use with mapping for keeping indexes in correct ordering function removeIndexed( uint256[] storage array, mapping(uint256 => uint256) storage indexes, uint256 id ) internal { uint256 lastId = array[array.length - 1]; uint256 index = indexes[id]; indexes[lastId] = index; indexes[id] = type(uint256).max; array[index] = lastId; array.pop(); } /// @notice Return a-b OR zero if a < b function sub0(uint32 a, uint32 b) internal pure returns (uint32) { return a > b ? a - b : 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../interfaces/IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (metatx/ERC2771Context.sol) pragma solidity ^0.8.1; import "../interfaces/IAppErrors.sol"; /** * @dev Context variant with ERC2771 support. */ // based on https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/metatx/ERC2771Context.sol abstract contract ERC2771Context { // for whitelist new relayers need to add new constants and update proxies address private constant GELATO_RELAY_1_BALANCE_ERC_2771 = 0xd8253782c45a12053594b9deB72d8e8aB2Fca54c; address private constant SACRA_RELAY = 0x52CEba41Da235Af367bFC0b0cCd3314cb901bB5F; function isTrustedForwarder(address forwarder) public view virtual returns (bool){ return forwarder == GELATO_RELAY_1_BALANCE_ERC_2771 || forwarder == SACRA_RELAY; } function _msgSender() internal view virtual returns (address sender) { if (isTrustedForwarder(msg.sender)) { // The assembly code is more direct than the Solidity version using `abi.decode`. /// @solidity memory-safe-assembly assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) } return sender; } else { return msg.sender; } } function _msgData() internal view virtual returns (bytes calldata) { if (isTrustedForwarder(msg.sender)) { return msg.data[: msg.data.length - 20]; } else { return msg.data; } } /// @notice Return true if given address is not a smart contract but a wallet address. /// @dev It is not 100% guarantee after EIP-3074 implementation, use it as an additional check. /// @return true if the address is a wallet. function _isNotSmartContract() internal view returns (bool) { return isTrustedForwarder(msg.sender) || msg.sender == tx.origin; } function onlyEOA() internal view { if (!_isNotSmartContract()) { revert IAppErrors.NotEOA(msg.sender); } } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 50 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_depositToken","type":"address"},{"internalType":"uint256","name":"_positionDepositAmount","type":"uint256"},{"internalType":"address","name":"_feeRecipient","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"PawnShopAlreadyAnnounced","type":"error"},{"inputs":[],"name":"PawnShopAlreadyClaimed","type":"error"},{"inputs":[],"name":"PawnShopAuctionBidNotFound","type":"error"},{"inputs":[],"name":"PawnShopAuctionEnded","type":"error"},{"inputs":[],"name":"PawnShopAuctionNotEnded","type":"error"},{"inputs":[],"name":"PawnShopBidAlreadyExists","type":"error"},{"inputs":[],"name":"PawnShopBidClosed","type":"error"},{"inputs":[],"name":"PawnShopBidNotFound","type":"error"},{"inputs":[],"name":"PawnShopIncorrect","type":"error"},{"inputs":[],"name":"PawnShopNewBidTooLow","type":"error"},{"inputs":[],"name":"PawnShopNoBids","type":"error"},{"inputs":[],"name":"PawnShopNotBorrower","type":"error"},{"inputs":[],"name":"PawnShopNotLender","type":"error"},{"inputs":[],"name":"PawnShopNotOwner","type":"error"},{"inputs":[],"name":"PawnShopPosFeeAbsurdlyHigh","type":"error"},{"inputs":[],"name":"PawnShopPosFeeForInstantDealForbidden","type":"error"},{"inputs":[],"name":"PawnShopPositionClosed","type":"error"},{"inputs":[],"name":"PawnShopPositionExecuted","type":"error"},{"inputs":[],"name":"PawnShopPositionNotExecuted","type":"error"},{"inputs":[],"name":"PawnShopTimeLock","type":"error"},{"inputs":[],"name":"PawnShopTooEarlyToClaim","type":"error"},{"inputs":[],"name":"PawnShopTooHighValue","type":"error"},{"inputs":[],"name":"PawnShopTooLowBid","type":"error"},{"inputs":[],"name":"PawnShopWrongAddressValue","type":"error"},{"inputs":[],"name":"PawnShopWrongAmounts","type":"error"},{"inputs":[],"name":"PawnShopWrongBid","type":"error"},{"inputs":[],"name":"PawnShopWrongBidAmount","type":"error"},{"inputs":[],"name":"PawnShopWrongId","type":"error"},{"inputs":[],"name":"PawnShopWrongUintValue","type":"error"},{"inputs":[],"name":"PawnShopZeroAToken","type":"error"},{"inputs":[],"name":"PawnShopZeroAddress","type":"error"},{"inputs":[],"name":"PawnShopZeroCToken","type":"error"},{"inputs":[],"name":"PawnShopZeroFeeRecipient","type":"error"},{"inputs":[],"name":"PawnShopZeroOwner","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bidId","type":"uint256"}],"name":"AuctionBidAccepted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bidId","type":"uint256"}],"name":"AuctionBidClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bidId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"lender","type":"address"}],"name":"AuctionBidOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bidId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"acquiredMoneyHolder","type":"address"},{"indexed":false,"internalType":"address","name":"lender","type":"address"}],"name":"BidExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAmount","type":"uint256"}],"name":"DepositAmountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldToken","type":"address"},{"indexed":false,"internalType":"address","name":"newToken","type":"address"}],"name":"DepositTokenChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRecipient","type":"address"},{"indexed":false,"internalType":"address","name":"newRecipient","type":"address"}],"name":"FeeRecipientChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"addressValue","type":"address"},{"indexed":false,"internalType":"uint256","name":"uintValue","type":"uint256"}],"name":"GovernanceActionAnnounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"PlatformFeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"}],"name":"PositionClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"}],"name":"PositionClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"},{"indexed":false,"internalType":"address","name":"collateralToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"acquiredToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"acquiredAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"posDurationBlocks","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"posFee","type":"uint256"}],"name":"PositionOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"posId","type":"uint256"}],"name":"PositionRedeemed","type":"event"},{"inputs":[],"name":"AUCTION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLATFORM_FEE_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIME_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"posId","type":"uint256"}],"name":"acceptAuctionBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IPawnShop.GovernanceAction","name":"id","type":"uint8"},{"internalType":"address","name":"addressValue","type":"address"},{"internalType":"uint256","name":"uintValue","type":"uint256"}],"name":"announceGovernanceAction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"auctionBidCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"posId","type":"uint256"}],"name":"auctionBidSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctionBids","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"posId","type":"uint256"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"open","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"borrowerPositions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"borrower","type":"address"}],"name":"borrowerPositionsSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegateContract","type":"address"},{"internalType":"bytes32","name":"_id","type":"bytes32"}],"name":"clearDelegatedVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bidId","type":"uint256"}],"name":"closeAuctionBid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"closePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createdBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createdTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_delegateContract","type":"address"},{"internalType":"bytes32","name":"_id","type":"bytes32"},{"internalType":"address","name":"_delegate","type":"address"}],"name":"delegateVotes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getAssetType","outputs":[{"internalType":"enum IPawnShop.AssetType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"bidId","type":"uint256"}],"name":"getAuctionBid","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"posId","type":"uint256"},{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"open","type":"bool"}],"internalType":"struct IPawnShop.AuctionBid","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"posId","type":"uint256"}],"name":"getPosition","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"depositToken","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"bool","name":"open","type":"bool"},{"internalType":"uint256","name":"minAuctionAmount","type":"uint256"},{"components":[{"internalType":"uint256","name":"posDurationBlocks","type":"uint256"},{"internalType":"uint256","name":"posFee","type":"uint256"},{"internalType":"uint256","name":"createdBlock","type":"uint256"},{"internalType":"uint256","name":"createdTs","type":"uint256"}],"internalType":"struct IPawnShop.PositionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"enum IPawnShop.AssetType","name":"collateralType","type":"uint8"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"collateralTokenId","type":"uint256"}],"internalType":"struct IPawnShop.PositionCollateral","name":"collateral","type":"tuple"},{"components":[{"internalType":"address","name":"acquiredToken","type":"address"},{"internalType":"uint256","name":"acquiredAmount","type":"uint256"}],"internalType":"struct IPawnShop.PositionAcquired","name":"acquired","type":"tuple"},{"components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint256","name":"posStartBlock","type":"uint256"},{"internalType":"uint256","name":"posStartTs","type":"uint256"},{"internalType":"uint256","name":"posEndTs","type":"uint256"}],"internalType":"struct IPawnShop.PositionExecution","name":"execution","type":"tuple"}],"internalType":"struct IPawnShop.Position","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"isERC20","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"isERC721","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastAuctionBidTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lenderOpenBids","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lenderPositions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lender","type":"address"}],"name":"lenderPositionsSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_collateralToken","type":"address"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"uint256","name":"_collateralTokenId","type":"uint256"},{"internalType":"address","name":"_acquiredToken","type":"address"},{"internalType":"uint256","name":"_acquiredAmount","type":"uint256"},{"internalType":"uint256","name":"_posDurationBlocks","type":"uint256"},{"internalType":"uint256","name":"_posFee","type":"uint256"},{"internalType":"uint256","name":"minAuctionAmount","type":"uint256"}],"name":"openPosition","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"openPositions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openPositionsSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPawnShop.IndexType","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"posIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"positionDepositToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"positionToBidIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"positions","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"depositToken","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"bool","name":"open","type":"bool"},{"internalType":"uint256","name":"minAuctionAmount","type":"uint256"},{"components":[{"internalType":"uint256","name":"posDurationBlocks","type":"uint256"},{"internalType":"uint256","name":"posFee","type":"uint256"},{"internalType":"uint256","name":"createdBlock","type":"uint256"},{"internalType":"uint256","name":"createdTs","type":"uint256"}],"internalType":"struct IPawnShop.PositionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"enum IPawnShop.AssetType","name":"collateralType","type":"uint8"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"collateralTokenId","type":"uint256"}],"internalType":"struct IPawnShop.PositionCollateral","name":"collateral","type":"tuple"},{"components":[{"internalType":"address","name":"acquiredToken","type":"address"},{"internalType":"uint256","name":"acquiredAmount","type":"uint256"}],"internalType":"struct IPawnShop.PositionAcquired","name":"acquired","type":"tuple"},{"components":[{"internalType":"address","name":"lender","type":"address"},{"internalType":"uint256","name":"posStartBlock","type":"uint256"},{"internalType":"uint256","name":"posStartTs","type":"uint256"},{"internalType":"uint256","name":"posEndTs","type":"uint256"}],"internalType":"struct IPawnShop.PositionExecution","name":"execution","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"positionsByAcquired","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"acquiredToken","type":"address"}],"name":"positionsByAcquiredSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"positionsByCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collateral","type":"address"}],"name":"positionsByCollateralSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newFeeRecipient","type":"address"}],"name":"setFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setPlatformFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setPositionDepositAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_value","type":"address"}],"name":"setPositionDepositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IPawnShop.GovernanceAction","name":"","type":"uint8"}],"name":"timeLocks","outputs":[{"internalType":"uint256","name":"time","type":"uint256"},{"internalType":"address","name":"addressValue","type":"address"},{"internalType":"uint256","name":"uintValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"toRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040526103e860035560016007556001600f553480156200002157600080fd5b50604051620046e2380380620046e2833981016040819052620000449162000108565b60016000556001600160a01b0384166200007157604051632de70ca360e11b815260040160405180910390fd5b6001600160a01b0381166200009957604051633cc5222160e11b815260040160405180910390fd5b600180546001600160a01b039586166001600160a01b03199182161790915560028054928616928216929092179091556005805493909416921691909117909155426080524360a0526004556200015c565b80516001600160a01b03811681146200010357600080fd5b919050565b600080600080608085870312156200011f57600080fd5b6200012a85620000eb565b93506200013a60208601620000eb565b9250604085015191506200015160608601620000eb565b905092959194509250565b60805160a0516145606200018260003960006104fa0152600061087201526145606000f3fe608060405234801561001057600080fd5b50600436106102ac5760003560e01c80638137884a11610173578063b8f1a962116100d4578063b8f1a962146106ce578063c50981a1146106e1578063c84d9665146106f4578063d2ec002514610776578063daa09e5414610789578063db006a751461079c578063db2dbb44146107af578063e0a09c68146107c2578063e5b595aa146107cc578063e74b981b146107df578063eb02c301146107f2578063eb07365f14610812578063f070ba031461086d578063ffa1ad741461089457600080fd5b80638137884a146105bc57806382bd0b8c146105c5578063884399be146105ce5780638da5cb5b146105d65780638e246762146105e9578063918f86741461061457806398584c0f1461061d57806399fbab88146106265780639c8ae0801461064f578063a126d60114610662578063a271e52514610675578063a27219e51461067f578063a93d789f146106a8578063b25a8ea3146106bb57600080fd5b806326232a2e1161021d57806326232a2e14610449578063263e0c1b14610452578063347d50c514610475578063379607f5146104bc5780633a5edc54146104cf5780633e87290b146104e25780634593144c146104f5578063469048401461051c57806352eb916f14610547578063572b6c051461055a578063598647f81461056d5780635a905e101461058057806363d5ab8d1461059357806381165ec61461059c57600080fd5b80624ce3d3146102b1578063032c49ed146102ed5780630580c0321461030d578063106f76351461032057806312e8e2c31461033557806313af40351461034857806314e5f4791461035b578063150b7a02146103845780631abda8e4146103af5780631c7c565a146103d85780631dcea853146103f85780632404e26d14610423578063248a19bb14610436575b600080fd5b6102da6102bf366004613e9d565b6001600160a01b03166000908152600c602052604090205490565b6040519081526020015b60405180910390f35b6103006102fb366004613e9d565b6108c6565b6040516102e49190613ef0565b6102da61031b366004613efe565b6108d7565b61033361032e366004613f28565b610908565b005b610333610343366004613f28565b610b9c565b610333610356366004613e9d565b610dc8565b6102da610369366004613e9d565b6001600160a01b03166000908152600a602052604090205490565b6103a2610392366004613f57565b630a85bd0160e11b949350505050565b6040516102e49190614033565b6102da6103bd366004613e9d565b6001600160a01b03166000908152600b602052604090205490565b6102da6103e6366004613f28565b60009081526012602052604090205490565b6102da610406366004614055565b600e60209081526000928352604080842090915290825290205481565b6102da610431366004613f28565b610fd7565b610333610444366004613f28565b610fe2565b6102da60035481565b610465610460366004613e9d565b6111aa565b60405190151581526020016102e4565b6104ad610483366004614073565b60066020526000908152604090208054600182015460029092015490916001600160a01b03169083565b6040516102e493929190614090565b6103336104ca366004613f28565b6111b5565b6102da6104dd3660046140af565b611363565b6103336104f0366004613efe565b611a37565b6102da7f000000000000000000000000000000000000000000000000000000000000000081565b60025461052f906001600160a01b031681565b6040516001600160a01b0390911681526020016102e4565b6102da610555366004613efe565b611ad0565b610465610568366004613e9d565b611aec565b61033361057b366004614119565b611b3a565b61033361058e36600461413b565b611c32565b6102da60075481565b6102da6105aa366004613f28565b60136020526000908152604090205481565b6102da6103e881565b6102da600f5481565b6009546102da565b60015461052f906001600160a01b031681565b6102da6105f7366004613efe565b601160209081526000928352604080842090915290825290205481565b6102da61271081565b6102da60045481565b610639610634366004613f28565b611db3565b6040516102e49a99989796959493929190614219565b61033361065d366004613f28565b611ee9565b610333610670366004613f28565b61213d565b6102da6201518081565b6102da61068d366004613e9d565b6001600160a01b03166000908152600d602052604090205490565b6102da6106b6366004613efe565b61249d565b6103336106c9366004613e9d565b6124b9565b6102da6106dc366004613efe565b6126a1565b6102da6106ef366004614119565b6126bd565b61073e610702366004613f28565b60106020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b03909116919060ff1685565b6040805195865260208601949094526001600160a01b039092169284019290925260608301919091521515608082015260a0016102e4565b6102da610784366004613f28565b6126d9565b610465610797366004613e9d565b6126fa565b6103336107aa366004613f28565b612705565b60055461052f906001600160a01b031681565b6102da6202a30081565b6103336107da366004614294565b6128fa565b6103336107ed366004613e9d565b61299d565b610805610800366004613f28565b612bac565b6040516102e491906142d0565b610825610820366004613f28565b612d1e565b6040516102e4919081518152602080830151908201526040808301516001600160a01b0316908201526060808301519082015260809182015115159181019190915260a00190565b6102da7f000000000000000000000000000000000000000000000000000000000000000081565b6108b9604051806040016040528060068152602001650312e302e31360d41b81525081565b6040516102e4919061438f565b60006108d182612db8565b92915050565b600c60205281600052604060002081815481106108f357600080fd5b90600052602060002001600091509150505481565b610910612e2d565b60008181526010602052604081206002810154815491926001600160a01b039091169190036109525760405163c6b3721b60e01b815260040160405180910390fd5b600482015460ff1661097757604051634f98164160e11b815260040160405180910390fd5b61097f612e57565b6001600160a01b0316816001600160a01b0316146109b057604051631d70504f60e01b815260040160405180910390fd5b600182015460009081526008602090815260408083208054845260139092528220549091426109e262015180846143f4565b1090506000426109f562015180856143f4565b610a0290621275006143f4565b85546000908152601260205260408120549290911092509015610a5f57845460009081526012602052604081208054610a3d90600190614407565b81548110610a4d57610a4d61441a565b60009182526020909120015489149150505b808015610a695750825b80610a72575080155b80610a825750600485015460ff16155b80610a8a5750815b610aa75760405163459b792d60e11b815260040160405180910390fd5b6001600160a01b03808716600090815260116020908152604080832089548452909152808220919091556004808a01805460ff19169055600d88015460038b0154925163a9059cbb60e01b815293169263a9059cbb92610b09928b9201614430565b6020604051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c9190614449565b50845460408051918252602082018a90527f6a87dc49655b8e89257f75d88376c42ba5c050bf610a2c3f76148f127947f9c8910160405180910390a150505050505050610b996001600055565b50565b6001546001600160a01b0316610bb0612e57565b6001600160a01b031614610bd75760405163e0305dbd60e01b815260040160405180910390fd5b6002600081815260066020908152604080516060810182527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace29548082527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace2a546001600160a01b0316938201939093527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace2b549181019190915284911580610c7e575080514211155b15610c9c5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615610ce157826001600160a01b031681602001516001600160a01b031614610ce1576040516342b28e8560e01b815260040160405180910390fd5b8115610d0b5781816040015114610d0b57604051636c72ff3b60e11b815260040160405180910390fd5b6103e8851115610d2e57604051633724f56f60e21b815260040160405180910390fd5b60035460408051918252602082018790527fc98a8b10b63c929f7799380bb4a0c444c713ebf74d8732f944c915034121aad1910160405180910390a1600385905560066000856004811115610d8557610d85613eb8565b6004811115610d9657610d96613eb8565b8152602081019190915260400160009081208181556001810180546001600160a01b0319169055600201555050505050565b6001546001600160a01b0316610ddc612e57565b6001600160a01b031614610e035760405163e0305dbd60e01b815260040160405180910390fd5b600080805260066020908152604080516060810182527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8548082527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f9546001600160a01b0316938201939093527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4fa549181019190915283918391901580610eab575080514211155b15610ec95760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615610f0e57826001600160a01b031681602001516001600160a01b031614610f0e576040516342b28e8560e01b815260040160405180910390fd5b8115610f385781816040015114610f3857604051636c72ff3b60e11b815260040160405180910390fd5b6001600160a01b038516610f5f57604051635e192a0160e11b815260040160405180910390fd5b6001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91610f9e916001600160a01b0390911690889061446b565b60405180910390a1600180546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b60006108d182612e79565b6001546001600160a01b0316610ff6612e57565b6001600160a01b03161461101d5760405163e0305dbd60e01b815260040160405180910390fd5b6003600081815260066020908152604080516060810182527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d2548082527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d3546001600160a01b0316938201939093527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d45491810191909152849115806110c4575080514211155b156110e25760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b0383161561112757826001600160a01b031681602001516001600160a01b031614611127576040516342b28e8560e01b815260040160405180910390fd5b8115611151578181604001511461115157604051636c72ff3b60e11b815260040160405180910390fd5b60045460408051918252602082018790527fe8a90a4e7ae8a56c5c24412551b21d6b4557535da5309263e34d818103e15096910160405180910390a18460048190555060066000856004811115610d8557610d85613eb8565b60006108d18261302d565b6111bd612e2d565b6000818152600860205260409020805482146111ec5760405163385f723560e11b815260040160405180910390fd5b6111f4612e57565b600f8201546001600160a01b0390811691161461122457604051631d70504f60e01b815260040160405180910390fd5b6006810154601082015460009161123a916143f4565b905043811061125c576040516387b9d9ff60e01b815260040160405180910390fd5b600482015460ff16611281576040516331e52e2f60e11b815260040160405180910390fd5b61128a826130a2565b6040805160808101909152600a830180546001600160a01b03811683526113049291906020830190600160a01b900460ff1660018111156112cd576112cd613eb8565b60018111156112de576112de613eb8565b815260200160018201548152602001600282015481525050306112ff612e57565b61313e565b61130d836132b7565b611315612e57565b6001600160a01b03167ffa6e92366c16d5c789e26dd0b930fddd4e37c6115049c4d123cb73c529362fa98460405161134f91815260200190565b60405180910390a25050610b996001600055565b600061136d612e2d565b61137a612710600a614485565b83111561139a576040516392c9fd0160e01b815260040160405180910390fd5b831580156113a757508215155b156113c5576040516311c309ef60e21b815260040160405180910390fd5b871580156113d1575086155b156113ef5760405163c404a2e560e01b815260040160405180910390fd5b6001600160a01b0389166114165760405163b44bebfb60e01b815260040160405180910390fd5b6001600160a01b03861661143d57604051638573c7c160e01b815260040160405180910390fd5b60006114488a612db8565b9050600081600181111561145e5761145e613eb8565b14801561146a57508815155b8015611474575087155b1580156114a85750600181600181111561149057611490613eb8565b14801561149b575088155b80156114a657508715155b155b156114c657604051633d0b0d4360e21b815260040160405180910390fd5b6114ce613d95565b60006040518060800160405280888152602001878152602001438152602001428152509050600060405180608001604052808e6001600160a01b0316815260200185600181111561152157611521613eb8565b815260208082018f905260409182018e9052815180830183526001600160a01b038e1681528082018d90528251608081018452600080825281840181905281850181905260608201528351610140810190945260075484529394509291908101611589612e57565b6001600160a01b0390811682526005541660208201526004546040820152600160608201819052608082018b905260a082019690965260c081019490945260e084019290925261010090920191909152805160098054808501825560008290527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01919091555490925061161d9190614407565b6000808052600e6020908152835182527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c81526040808320939093556001600160a01b038e16808352600a8252928220845181546001808201845583865293852001559290915290546116909190614407565b60016000818152600e6020908152845182527fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be95820781526040808320949094556001600160a01b038c16808352600b82529382208551815480860183558285529284209092019190915592905290546117079190614407565b60026000908152600e6020908152835182527f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f048190526040812091909155600c9061174f612e57565b6001600160a01b031681526020808201929092526040016000908120835181546001818101845592845293832090930192909255600c9061178e612e57565b6001600160a01b031681526020810191909152604001600020546117b29190614407565b60036000818152600e6020908152845182527fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c9081448152604080832094909455845182526008808252918490208551815585820151600180830180546001600160a01b03199081166001600160a01b03948516179091558888015160028501805483169185169190911790556060808a015197850197909755608089015160048501805460ff191691151591909117905560a0890151600585015560c08901518051600686015580860151600786015597880151958401959095559590940151600982015560e08601518051600a83018054958616919096169081178655928101518796929591949193909284926001600160a81b03191690911790600160a01b9084908111156118e3576118e3613eb8565b021790555060408281015160018301556060928301516002909201919091556101008401518051600d850180546001600160a01b039283166001600160a01b031991821617909155602092830151600e870155610120909601518051600f870180549190931697169690961790558401516010840155830151601183015591909101516012909101556007805490600061197c8361449c565b9091555050805161198c90613358565b6119a28160e0015161199c612e57565b3061313e565b6119aa612e57565b8151604080519182526001600160a01b038e811660208401528282018e9052606083018d90528b8116608084015260a083018b905260c083018a905260e0830189905290519216917fb3a36ac05090f711e42b60c13a82d445eeea0e6aa81bb29143354d10f02de515918190036101000190a251915050611a2b6001600055565b98975050505050505050565b6001546001600160a01b0316611a4b612e57565b6001600160a01b031614611a725760405163e0305dbd60e01b815260040160405180910390fd5b60405163785f6df160e11b8152600481018290526001600160a01b0383169063f0bedbe290602401600060405180830381600087803b158015611ab457600080fd5b505af1158015611ac8573d6000803e3d6000fd5b505050505050565b600b60205281600052604060002081815481106108f357600080fd5b60006001600160a01b03821673d8253782c45a12053594b9deb72d8e8ab2fca54c14806108d157506001600160a01b0382167352ceba41da235af367bfc0b0ccd3314cb901bb5f1492915050565b611b42612e2d565b600082815260086020526040902080548314611b715760405163385f723560e11b815260040160405180910390fd5b600481015460ff16611b96576040516331e52e2f60e11b815260040160405180910390fd5b600f8101546001600160a01b031615611bc257604051634189c8eb60e01b815260040160405180910390fd5b600e81015415611c1157600e8101548214611bf057604051632b0706f360e11b815260040160405180910390fd5b611c0c81600084611bff612e57565b611c07612e57565b6133b9565b611c23565b611c238183611c1e612e57565b61387b565b50611c2e6001600055565b5050565b6001546001600160a01b0316611c46612e57565b6001600160a01b031614611c6d5760405163e0305dbd60e01b815260040160405180910390fd5b60066000846004811115611c8357611c83613eb8565b6004811115611c9457611c94613eb8565b815260208101919091526040016000205415611cc3576040516327b85cbd60e11b815260040160405180910390fd5b60405180606001604052806202a30042611cdd91906143f4565b81526001600160a01b038416602082015260400182905260066000856004811115611d0a57611d0a613eb8565b6004811115611d1b57611d1b613eb8565b8152602080820192909252604090810160002083518155918301516001830180546001600160a01b0319166001600160a01b0390921691909117905591909101516002909101557f86496aa80f046dc4404f94bce44e24d8e17dc1bb123e8c774ff23ce0e6f0aabe836004811115611d9557611d95613eb8565b8383604051611da693929190614090565b60405180910390a1505050565b600860208181526000928352604092839020805460018083015460028401546003850154600486015460058701548a5160808082018d5260068a0154825260078a0154828c01529a890154818d0152600989015460608201528b519a8b01909b52600a880180546001600160a01b038181168d52989c9689169b9590981699939860ff938416989297909594919391850192600160a01b900490911690811115611e5f57611e5f613eb8565b6001811115611e7057611e70613eb8565b8152600182015460208083019190915260029092015460409182015280518082018252600d8501546001600160a01b039081168252600e860154828501528251608081018452600f870154909116815260108601549381019390935260118501549183019190915260129093015460608201529091908a565b611ef1612e2d565b6000818152601360205260409020544290611f109062015180906143f4565b10611f2e5760405163459b792d60e11b815260040160405180910390fd5b6000818152601260205260408120549003611f5c57604051630ebe58ef60e11b815260040160405180910390fd5b60008181526012602052604081208054611f7890600190614407565b81548110611f8857611f8861441a565b600091825260208083209091015480835260109091526040822080549193509103611fc657604051630dcea1fb60e31b815260040160405180910390fd5b600481015460ff16611feb57604051634f98164160e11b815260040160405180910390fd5b8281600101541461200f57604051630c17e23d60e31b815260040160405180910390fd5b6000838152600860205260409020612025612e57565b60018201546001600160a01b039081169116146120555760405163632e534d60e01b815260040160405180910390fd5b600481015460ff1661207a576040516331e52e2f60e11b815260040160405180910390fd5b6003820154600e820181905560028301546120a491839186919030906001600160a01b03166133b9565b60028201546001600160a01b031660009081526011602090815260408083208454845290915281205560048201805460ff191690556120e1612e57565b6001600160a01b03167f493e1e7f0e9233f36d4697a11b43b59a1507e08e3c1f920549858785646ac179858460000154604051612128929190918252602082015260400190565b60405180910390a2505050610b996001600055565b612145612e2d565b6000818152600860205260409020805482146121745760405163385f723560e11b815260040160405180910390fd5b61217c612e57565b60018201546001600160a01b039081169116146121ac5760405163632e534d60e01b815260040160405180910390fd5b600f8101546001600160a01b0316156121d857604051634189c8eb60e01b815260040160405180910390fd5b600481015460ff166121fd576040516331e52e2f60e11b815260040160405180910390fd5b6040805161014081018252825481526001808401546001600160a01b0390811660208085019190915260028601548216848601526003860154606080860191909152600487015460ff9081161515608080880191909152600589015460a08801528751808201895260068a0154815260078a01548186015260088a0154818a015260098a01549381019390935260c08701929092528651918201909652600a87018054938416825261236496889560e08801959394929392850192600160a01b9004909116908111156122d2576122d2613eb8565b60018111156122e3576122e3613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f860154909116815260108501549181019190915260118401548183015260129093015460608401520152613b9b565b60018101546001600160a01b03166000908152600c602052604081206123b391600e9060035b600481111561239b5761239b613eb8565b81526020019081526020016000208360000154613c26565b6040805160808101909152600a820180546001600160a01b03811683526124339291906020830190600160a01b900460ff1660018111156123f6576123f6613eb8565b600181111561240757612407613eb8565b8152600182810154602083015260029092015460409091015283015430906001600160a01b031661313e565b61243c826132b7565b60048101805460ff19169055612450612e57565b6001600160a01b03167fa9e0cdf27a7965d21573ebb808fbcb2c2a1cfd656e1ecf3f82549437b47406778360405161248a91815260200190565b60405180910390a250610b996001600055565b600d60205281600052604060002081815481106108f357600080fd5b6001546001600160a01b03166124cd612e57565b6001600160a01b0316146124f45760405163e0305dbd60e01b815260040160405180910390fd5b6004600081815260066020908152604080516060810182527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eed548082527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eee546001600160a01b0316938201939093527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eef5491810191909152849291158061259c575080514211155b156125ba5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b038316156125ff57826001600160a01b031681602001516001600160a01b0316146125ff576040516342b28e8560e01b815260040160405180910390fd5b8115612629578181604001511461262957604051636c72ff3b60e11b815260040160405180910390fd5b6005546040517f709d4a2a735567787a6859678c4b234a262c4355d6d33796ddb4ef59f80c662191612668916001600160a01b0390911690889061446b565b60405180910390a1600580546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b600a60205281600052604060002081815481106108f357600080fd5b601260205281600052604060002081815481106108f357600080fd5b600981815481106126e957600080fd5b600091825260209091200154905081565b60006108d182613c31565b61270d612e2d565b60008181526008602052604090208054821461273c5760405163385f723560e11b815260040160405180910390fd5b612744612e57565b60018201546001600160a01b039081169116146127745760405163632e534d60e01b815260040160405180910390fd5b600f8101546001600160a01b031661279f5760405163c4912b5360e01b815260040160405180910390fd5b600481015460ff166127c4576040516331e52e2f60e11b815260040160405180910390fd5b6127cd816130a2565b60006127d883612e79565b600d8301549091506001600160a01b03166323b872dd6127f6612e57565b600f8501546040516001600160e01b031960e085901b16815261282892916001600160a01b03169086906004016144b5565b6020604051808303816000875af1158015612847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286b9190614449565b506040805160808101909152600a830180546001600160a01b03811683526128af9291906020830190600160a01b900460ff1660018111156112cd576112cd613eb8565b6128b8836132b7565b6128c0612e57565b6001600160a01b03167f573152bdc3a6b0ce7d310a9875f49776804dd1634202817985b567975731711f8460405161134f91815260200190565b6001546001600160a01b031661290e612e57565b6001600160a01b0316146129355760405163e0305dbd60e01b815260040160405180910390fd5b6040516317b0dca160e31b8152600481018390526001600160a01b03828116602483015284169063bd86e508906044015b600060405180830381600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b50505050505050565b6001546001600160a01b03166129b1612e57565b6001600160a01b0316146129d85760405163e0305dbd60e01b815260040160405180910390fd5b6001600081815260066020908152604080516060810182527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a31548082527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a32546001600160a01b0316938201939093527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a3354918101919091528492911580612a80575080514211155b15612a9e5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615612ae357826001600160a01b031681602001516001600160a01b031614612ae3576040516342b28e8560e01b815260040160405180910390fd5b8115612b0d5781816040015114612b0d57604051636c72ff3b60e11b815260040160405180910390fd5b6001600160a01b038516612b3457604051635e192a0160e11b815260040160405180910390fd5b6002546040517f0bc21fe5c3ab742ff1d15b5c4477ffbacf1167e618228078fa625edebe7f331d91612b73916001600160a01b0390911690889061446b565b60405180910390a1600280546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b612bb4613d95565b600082815260086020818152604092839020835161014081018552815481526001808301546001600160a01b039081168386015260028401548116838801526003840154606080850191909152600485015460ff9081161515608080870191909152600587015460a087015289518082018b52600688015481526007880154818a015298870154898b015260098701549289019290925260c08501979097528751908101909752600a8401805491821688529296939560e0880195850192600160a01b9092041690811115612c8b57612c8b613eb8565b6001811115612c9c57612c9c613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f86015490911681526010850154918101919091526011840154818301526012909301546060840152015292915050565b612d5b6040518060a00160405280600081526020016000815260200160006001600160a01b03168152602001600081526020016000151581525090565b50600090815260106020908152604091829020825160a0810184528154815260018201549281019290925260028101546001600160a01b0316928201929092526003820154606082015260049091015460ff161515608082015290565b6000612dc382613c31565b15612dd057506001919050565b612dd98261302d565b15612de657506000919050565b60405162461bcd60e51b8152602060048201526012602482015271151414ce88155b9adb9bdddb88185cdcd95d60721b60448201526064015b60405180910390fd5b919050565b600260005403612e5057604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6000612e6233611aec565b15612e74575060131936013560601c90565b503390565b6000818152600860208181526040808420815161014081018352815481526001808301546001600160a01b039081168387015260028401548116838601526003840154606080850191909152600485015460ff9081161515608080870191909152600587015460a087015287518082018952600688015481526007880154818b0152998701548a8901526009870154928a019290925260c08501989098528551908101909552600a84018054918216865288979396949560e08801959094919390850192600160a01b900490911690811115612f5757612f57613eb8565b6001811115612f6857612f68613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f8601549091168152601085015481830152601185015481840152601290940154606085015291019190915260c082015181015161010083015190910151919250612710916130089190614485565b61301291906144d9565b8161010001516020015161302691906143f4565b9392505050565b6000816001600160a01b03166318160ddd6175306040518263ffffffff1660e01b81526004016020604051808303818786fa9350505050801561308d575060408051601f3d908101601f1916820190925261308a918101906144fb565b60015b61309957506000919050565b50600192915050565b6012810154156130c55760405163ea9883a360e01b815260040160405180910390fd5b60048101805460ff1916905542601282015560018101546001600160a01b03166000908152600c6020526040812061310191600e90600361238a565b600f8101546001600160a01b031615610b9957600f8101546001600160a01b03166000908152600d60205260408120610b9991600e90600461238a565b60008360200151600181111561315657613156613eb8565b0361321f57306001600160a01b038316036131e9578251604080850151905163a9059cbb60e01b81526001600160a01b039092169163a9059cbb916131a091859190600401614430565b6020604051808303816000875af11580156131bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e39190614449565b50505050565b825160408085015190516323b872dd60e01b81526001600160a01b03909216916323b872dd916131a091869186916004016144b5565b60018360200151600181111561323757613237613eb8565b0361327257825160608401516040516323b872dd60e01b81526001600160a01b03909216916323b872dd9161296691869186916004016144b5565b60405162461bcd60e51b81526020600482015260156024820152745450533a2057726f6e67206173736574207479706560581b6044820152606401612e1f565b505050565b600081815260086020526040902060028101546001600160a01b031615611c2e5760028101546001820154600383015460405163a9059cbb60e01b81526001600160a01b039384169363a9059cbb9361331593911691600401614430565b6020604051808303816000875af1158015613334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b29190614449565b600081815260086020526040902060028101546001600160a01b031615611c2e576002810154600182015460038301546040516323b872dd60e01b81526001600160a01b03938416936323b872dd93613315939116913091906004016144b5565b6000612710600354856133cc9190614485565b6133d691906144d9565b905060006133e48286614407565b9050306001600160a01b0385160361347957600d870154600188015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92613430929116908590600401614430565b6020604051808303816000875af115801561344f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134739190614449565b50613575565b600d87015460018801546040516323b872dd60e01b81526001600160a01b03928316926323b872dd926134b69289929091169086906004016144b5565b6020604051808303816000875af11580156134d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f99190614449565b50600d8701546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90613530908790309087906004016144b5565b6020604051808303816000875af115801561354f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135739190614449565b505b600d87015461358d906001600160a01b031683613caf565b8287600f0160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055504387600f01600101819055504287600f01600201819055506137178760405180610140016040529081600082015481526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152602001600682016040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250508152602001600a82016040518060800160405290816000820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016000820160149054906101000a900460ff1660018111156122d2576122d2613eb8565b6001600160a01b0383166000818152600d6020908152604082208a5481546001818101845583865293852001559290915290546137549190614407565b875460009081527fa1d6913cd9e08c872be3e7525cca82e4fc0fc298a783f19022be725b19be685a602052604081209190915560068801549003613819576040805160808101909152600a880180546001600160a01b03811683526138059291906020830190600160a01b900460ff1660018111156137d5576137d5613eb8565b60018111156137e6576137e6613eb8565b815260200160018201548152602001600282015481525050308561313e565b8654613810906132b7565b613819876130a2565b8654604080519182526020820188905281018690526001600160a01b038086166060830152841660808201527fb4a7227fb0dfeb98811f5d56165a8829f9656773c1b9dc94821d75c46f42f7639060a00160405180910390a150505050505050565b6001600160a01b038116600090815260116020908152604080832086548452909152902054156138be5760405163aca2258560e01b815260040160405180910390fd5b82600501548210156138e3576040516304f3be9f60e11b815260040160405180910390fd5b8254600090815260126020526040902054156139c9578254600090815260136020526040902054429061391a9062015180906143f4565b116139385760405163a508237960e01b815260040160405180910390fd5b82546000908152601260205260408120805461395690600190614407565b815481106139665761396661441a565b9060005260206000200154905060006010600083815260200190815260200160002090508360648260030154606e61399e9190614485565b6139a891906144d9565b106139c65760405163066881a960e51b815260040160405180910390fd5b50505b6040805160a081018252600f548152845460208083018290526001600160a01b038086168486018190526060850188905260016080860181905260009485526012845286852086518154928301825590865284862090910155885480855286852054918552601184528685209085529092529390912055600d8501549091166323b872dd613a55612e57565b30866040518463ffffffff1660e01b8152600401613a75939291906144b5565b6020604051808303816000875af1158015613a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab89190614449565b50835460009081526013602090815260408083204290558351835260108252808320845181559184015160018301558301516002820180546001600160a01b0319166001600160a01b039092169190911790556060830151600382015560808301516004909101805460ff1916911515919091179055600f805491613b3c8361449c565b90915550508354815160408051928352602083019190915281018490526001600160a01b03831660608201527f212de920a843943385be4d0be6f5375802a6c0eb13258959f94184f8599aa1f19060800160405180910390a150505050565b613bcf6009600e6000805b6004811115613bb757613bb7613eb8565b81526020019081526020016000208360000151613c26565b60e0810151516001600160a01b03166000908152600a60205260408120613bfa91600e906001613ba6565b610100810151516001600160a01b03166000908152600b60205260408120610b9991600e906002613ba6565b6132b2838383613cef565b6000816001600160a01b03166301ffc9a76175306380ac58cd60e01b6040518363ffffffff1660e01b8152600401613c699190614033565b6020604051808303818786fa93505050508015613ca3575060408051601f3d908101601f19168201909252613ca091810190614449565b60015b6108d157506000919050565b80600003613cbb575050565b60025460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261331592909116908590600401614430565b82546000908490613d0290600190614407565b81548110613d1257613d1261441a565b600091825260208083209091015484835290859052604080832080548385529184208290559285905260001990925585549092508290869083908110613d5a57613d5a61441a565b906000526020600020018190555084805480613d7857613d78614514565b600190038181906000526020600020016000905590555050505050565b6040518061014001604052806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160001515815260200160008152602001613e0a6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526040805160808101825260008082526020808301829052828401829052606083018290528085019290925282518084018452818152918201529101908152602001613e81604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b905290565b80356001600160a01b0381168114612e2857600080fd5b600060208284031215613eaf57600080fd5b61302682613e86565b634e487b7160e01b600052602160045260246000fd5b60028110613eec57634e487b7160e01b600052602160045260246000fd5b9052565b602081016108d18284613ece565b60008060408385031215613f1157600080fd5b613f1a83613e86565b946020939093013593505050565b600060208284031215613f3a57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215613f6d57600080fd5b613f7685613e86565b9350613f8460208601613e86565b925060408501359150606085013567ffffffffffffffff80821115613fa857600080fd5b818701915087601f830112613fbc57600080fd5b813581811115613fce57613fce613f41565b604051601f8201601f19908116603f01168101908382118183101715613ff657613ff6613f41565b816040528281528a602084870101111561400f57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6001600160e01b031991909116815260200190565b60058110610b9957600080fd5b6000806040838503121561406857600080fd5b8235613f1a81614048565b60006020828403121561408557600080fd5b813561302681614048565b9283526001600160a01b03919091166020830152604082015260600190565b600080600080600080600080610100898b0312156140cc57600080fd5b6140d589613e86565b975060208901359650604089013595506140f160608a01613e86565b979a969950949760808101359660a0820135965060c0820135955060e0909101359350915050565b6000806040838503121561412c57600080fd5b50508035926020909101359150565b60008060006060848603121561415057600080fd5b833561415b81614048565b925061416960208501613e86565b9150604084013590509250925092565b805182526020810151602083015260408101516040830152606081015160608301525050565b80516001600160a01b03168252602080820151906141bf90840182613ece565b5060408181015190830152606090810151910152565b80516001600160a01b03168252602090810151910152565b80516001600160a01b031682526020808201519083015260408082015190830152606090810151910152565b8a81526001600160a01b038a811660208301528916604082015260608101889052861515608082015260a08101869052610280810161425b60c0830187614179565b61426961014083018661419f565b6142776101c08301856141d5565b6142856102008301846141ed565b9b9a5050505050505050505050565b6000806000606084860312156142a957600080fd5b6142b284613e86565b9250602084013591506142c760408501613e86565b90509250925092565b815181526020808301516102808301916142f4908401826001600160a01b03169052565b50604083015161430f60408401826001600160a01b03169052565b5060608301516060830152608083015161432d608084018215159052565b5060a083015160a083015260c083015161434a60c0840182614179565b5060e083015161435e61014084018261419f565b506101008301516143736101c08401826141d5565b506101208301516143886102008401826141ed565b5092915050565b60006020808352835180602085015260005b818110156143bd578581018301518582016040015282016143a1565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b808201808211156108d1576108d16143de565b818103818111156108d1576108d16143de565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03929092168252602082015260400190565b60006020828403121561445b57600080fd5b8151801515811461302657600080fd5b6001600160a01b0392831681529116602082015260400190565b80820281158282048414176108d1576108d16143de565b6000600182016144ae576144ae6143de565b5060010190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6000826144f657634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561450d57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d25f358537997ae8171a8b21f2a548812a45b87cd8b9376ce9e8e3ed7c0f80ec64736f6c63430008170033000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a940000000000000000000000007ad5935ea295c4e743e4f2f5b4cda951f41223c20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a94
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102ac5760003560e01c80638137884a11610173578063b8f1a962116100d4578063b8f1a962146106ce578063c50981a1146106e1578063c84d9665146106f4578063d2ec002514610776578063daa09e5414610789578063db006a751461079c578063db2dbb44146107af578063e0a09c68146107c2578063e5b595aa146107cc578063e74b981b146107df578063eb02c301146107f2578063eb07365f14610812578063f070ba031461086d578063ffa1ad741461089457600080fd5b80638137884a146105bc57806382bd0b8c146105c5578063884399be146105ce5780638da5cb5b146105d65780638e246762146105e9578063918f86741461061457806398584c0f1461061d57806399fbab88146106265780639c8ae0801461064f578063a126d60114610662578063a271e52514610675578063a27219e51461067f578063a93d789f146106a8578063b25a8ea3146106bb57600080fd5b806326232a2e1161021d57806326232a2e14610449578063263e0c1b14610452578063347d50c514610475578063379607f5146104bc5780633a5edc54146104cf5780633e87290b146104e25780634593144c146104f5578063469048401461051c57806352eb916f14610547578063572b6c051461055a578063598647f81461056d5780635a905e101461058057806363d5ab8d1461059357806381165ec61461059c57600080fd5b80624ce3d3146102b1578063032c49ed146102ed5780630580c0321461030d578063106f76351461032057806312e8e2c31461033557806313af40351461034857806314e5f4791461035b578063150b7a02146103845780631abda8e4146103af5780631c7c565a146103d85780631dcea853146103f85780632404e26d14610423578063248a19bb14610436575b600080fd5b6102da6102bf366004613e9d565b6001600160a01b03166000908152600c602052604090205490565b6040519081526020015b60405180910390f35b6103006102fb366004613e9d565b6108c6565b6040516102e49190613ef0565b6102da61031b366004613efe565b6108d7565b61033361032e366004613f28565b610908565b005b610333610343366004613f28565b610b9c565b610333610356366004613e9d565b610dc8565b6102da610369366004613e9d565b6001600160a01b03166000908152600a602052604090205490565b6103a2610392366004613f57565b630a85bd0160e11b949350505050565b6040516102e49190614033565b6102da6103bd366004613e9d565b6001600160a01b03166000908152600b602052604090205490565b6102da6103e6366004613f28565b60009081526012602052604090205490565b6102da610406366004614055565b600e60209081526000928352604080842090915290825290205481565b6102da610431366004613f28565b610fd7565b610333610444366004613f28565b610fe2565b6102da60035481565b610465610460366004613e9d565b6111aa565b60405190151581526020016102e4565b6104ad610483366004614073565b60066020526000908152604090208054600182015460029092015490916001600160a01b03169083565b6040516102e493929190614090565b6103336104ca366004613f28565b6111b5565b6102da6104dd3660046140af565b611363565b6103336104f0366004613efe565b611a37565b6102da7f000000000000000000000000000000000000000000000000000000000003887781565b60025461052f906001600160a01b031681565b6040516001600160a01b0390911681526020016102e4565b6102da610555366004613efe565b611ad0565b610465610568366004613e9d565b611aec565b61033361057b366004614119565b611b3a565b61033361058e36600461413b565b611c32565b6102da60075481565b6102da6105aa366004613f28565b60136020526000908152604090205481565b6102da6103e881565b6102da600f5481565b6009546102da565b60015461052f906001600160a01b031681565b6102da6105f7366004613efe565b601160209081526000928352604080842090915290825290205481565b6102da61271081565b6102da60045481565b610639610634366004613f28565b611db3565b6040516102e49a99989796959493929190614219565b61033361065d366004613f28565b611ee9565b610333610670366004613f28565b61213d565b6102da6201518081565b6102da61068d366004613e9d565b6001600160a01b03166000908152600d602052604090205490565b6102da6106b6366004613efe565b61249d565b6103336106c9366004613e9d565b6124b9565b6102da6106dc366004613efe565b6126a1565b6102da6106ef366004614119565b6126bd565b61073e610702366004613f28565b60106020526000908152604090208054600182015460028301546003840154600490940154929391926001600160a01b03909116919060ff1685565b6040805195865260208601949094526001600160a01b039092169284019290925260608301919091521515608082015260a0016102e4565b6102da610784366004613f28565b6126d9565b610465610797366004613e9d565b6126fa565b6103336107aa366004613f28565b612705565b60055461052f906001600160a01b031681565b6102da6202a30081565b6103336107da366004614294565b6128fa565b6103336107ed366004613e9d565b61299d565b610805610800366004613f28565b612bac565b6040516102e491906142d0565b610825610820366004613f28565b612d1e565b6040516102e4919081518152602080830151908201526040808301516001600160a01b0316908201526060808301519082015260809182015115159181019190915260a00190565b6102da7f000000000000000000000000000000000000000000000000000000006756ad2081565b6108b9604051806040016040528060068152602001650312e302e31360d41b81525081565b6040516102e4919061438f565b60006108d182612db8565b92915050565b600c60205281600052604060002081815481106108f357600080fd5b90600052602060002001600091509150505481565b610910612e2d565b60008181526010602052604081206002810154815491926001600160a01b039091169190036109525760405163c6b3721b60e01b815260040160405180910390fd5b600482015460ff1661097757604051634f98164160e11b815260040160405180910390fd5b61097f612e57565b6001600160a01b0316816001600160a01b0316146109b057604051631d70504f60e01b815260040160405180910390fd5b600182015460009081526008602090815260408083208054845260139092528220549091426109e262015180846143f4565b1090506000426109f562015180856143f4565b610a0290621275006143f4565b85546000908152601260205260408120549290911092509015610a5f57845460009081526012602052604081208054610a3d90600190614407565b81548110610a4d57610a4d61441a565b60009182526020909120015489149150505b808015610a695750825b80610a72575080155b80610a825750600485015460ff16155b80610a8a5750815b610aa75760405163459b792d60e11b815260040160405180910390fd5b6001600160a01b03808716600090815260116020908152604080832089548452909152808220919091556004808a01805460ff19169055600d88015460038b0154925163a9059cbb60e01b815293169263a9059cbb92610b09928b9201614430565b6020604051808303816000875af1158015610b28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b4c9190614449565b50845460408051918252602082018a90527f6a87dc49655b8e89257f75d88376c42ba5c050bf610a2c3f76148f127947f9c8910160405180910390a150505050505050610b996001600055565b50565b6001546001600160a01b0316610bb0612e57565b6001600160a01b031614610bd75760405163e0305dbd60e01b815260040160405180910390fd5b6002600081815260066020908152604080516060810182527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace29548082527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace2a546001600160a01b0316938201939093527f8819ef417987f8ae7a81f42cdfb18815282fe989326fbff903d13cf0e03ace2b549181019190915284911580610c7e575080514211155b15610c9c5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615610ce157826001600160a01b031681602001516001600160a01b031614610ce1576040516342b28e8560e01b815260040160405180910390fd5b8115610d0b5781816040015114610d0b57604051636c72ff3b60e11b815260040160405180910390fd5b6103e8851115610d2e57604051633724f56f60e21b815260040160405180910390fd5b60035460408051918252602082018790527fc98a8b10b63c929f7799380bb4a0c444c713ebf74d8732f944c915034121aad1910160405180910390a1600385905560066000856004811115610d8557610d85613eb8565b6004811115610d9657610d96613eb8565b8152602081019190915260400160009081208181556001810180546001600160a01b0319169055600201555050505050565b6001546001600160a01b0316610ddc612e57565b6001600160a01b031614610e035760405163e0305dbd60e01b815260040160405180910390fd5b600080805260066020908152604080516060810182527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8548082527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f9546001600160a01b0316938201939093527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4fa549181019190915283918391901580610eab575080514211155b15610ec95760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615610f0e57826001600160a01b031681602001516001600160a01b031614610f0e576040516342b28e8560e01b815260040160405180910390fd5b8115610f385781816040015114610f3857604051636c72ff3b60e11b815260040160405180910390fd5b6001600160a01b038516610f5f57604051635e192a0160e11b815260040160405180910390fd5b6001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c91610f9e916001600160a01b0390911690889061446b565b60405180910390a1600180546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b60006108d182612e79565b6001546001600160a01b0316610ff6612e57565b6001600160a01b03161461101d5760405163e0305dbd60e01b815260040160405180910390fd5b6003600081815260066020908152604080516060810182527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d2548082527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d3546001600160a01b0316938201939093527f75f96ab15d697e93042dc45b5c896c4b27e89bb6eaf39475c5c371cb2513f7d45491810191909152849115806110c4575080514211155b156110e25760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b0383161561112757826001600160a01b031681602001516001600160a01b031614611127576040516342b28e8560e01b815260040160405180910390fd5b8115611151578181604001511461115157604051636c72ff3b60e11b815260040160405180910390fd5b60045460408051918252602082018790527fe8a90a4e7ae8a56c5c24412551b21d6b4557535da5309263e34d818103e15096910160405180910390a18460048190555060066000856004811115610d8557610d85613eb8565b60006108d18261302d565b6111bd612e2d565b6000818152600860205260409020805482146111ec5760405163385f723560e11b815260040160405180910390fd5b6111f4612e57565b600f8201546001600160a01b0390811691161461122457604051631d70504f60e01b815260040160405180910390fd5b6006810154601082015460009161123a916143f4565b905043811061125c576040516387b9d9ff60e01b815260040160405180910390fd5b600482015460ff16611281576040516331e52e2f60e11b815260040160405180910390fd5b61128a826130a2565b6040805160808101909152600a830180546001600160a01b03811683526113049291906020830190600160a01b900460ff1660018111156112cd576112cd613eb8565b60018111156112de576112de613eb8565b815260200160018201548152602001600282015481525050306112ff612e57565b61313e565b61130d836132b7565b611315612e57565b6001600160a01b03167ffa6e92366c16d5c789e26dd0b930fddd4e37c6115049c4d123cb73c529362fa98460405161134f91815260200190565b60405180910390a25050610b996001600055565b600061136d612e2d565b61137a612710600a614485565b83111561139a576040516392c9fd0160e01b815260040160405180910390fd5b831580156113a757508215155b156113c5576040516311c309ef60e21b815260040160405180910390fd5b871580156113d1575086155b156113ef5760405163c404a2e560e01b815260040160405180910390fd5b6001600160a01b0389166114165760405163b44bebfb60e01b815260040160405180910390fd5b6001600160a01b03861661143d57604051638573c7c160e01b815260040160405180910390fd5b60006114488a612db8565b9050600081600181111561145e5761145e613eb8565b14801561146a57508815155b8015611474575087155b1580156114a85750600181600181111561149057611490613eb8565b14801561149b575088155b80156114a657508715155b155b156114c657604051633d0b0d4360e21b815260040160405180910390fd5b6114ce613d95565b60006040518060800160405280888152602001878152602001438152602001428152509050600060405180608001604052808e6001600160a01b0316815260200185600181111561152157611521613eb8565b815260208082018f905260409182018e9052815180830183526001600160a01b038e1681528082018d90528251608081018452600080825281840181905281850181905260608201528351610140810190945260075484529394509291908101611589612e57565b6001600160a01b0390811682526005541660208201526004546040820152600160608201819052608082018b905260a082019690965260c081019490945260e084019290925261010090920191909152805160098054808501825560008290527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01919091555490925061161d9190614407565b6000808052600e6020908152835182527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c81526040808320939093556001600160a01b038e16808352600a8252928220845181546001808201845583865293852001559290915290546116909190614407565b60016000818152600e6020908152845182527fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be95820781526040808320949094556001600160a01b038c16808352600b82529382208551815480860183558285529284209092019190915592905290546117079190614407565b60026000908152600e6020908152835182527f9adb202b1492743bc00c81d33cdc6423fa8c79109027eb6a845391e8fc1f048190526040812091909155600c9061174f612e57565b6001600160a01b031681526020808201929092526040016000908120835181546001818101845592845293832090930192909255600c9061178e612e57565b6001600160a01b031681526020810191909152604001600020546117b29190614407565b60036000818152600e6020908152845182527fe0283e559c29e31ee7f56467acc9dd307779c843a883aeeb3bf5c6128c9081448152604080832094909455845182526008808252918490208551815585820151600180830180546001600160a01b03199081166001600160a01b03948516179091558888015160028501805483169185169190911790556060808a015197850197909755608089015160048501805460ff191691151591909117905560a0890151600585015560c08901518051600686015580860151600786015597880151958401959095559590940151600982015560e08601518051600a83018054958616919096169081178655928101518796929591949193909284926001600160a81b03191690911790600160a01b9084908111156118e3576118e3613eb8565b021790555060408281015160018301556060928301516002909201919091556101008401518051600d850180546001600160a01b039283166001600160a01b031991821617909155602092830151600e870155610120909601518051600f870180549190931697169690961790558401516010840155830151601183015591909101516012909101556007805490600061197c8361449c565b9091555050805161198c90613358565b6119a28160e0015161199c612e57565b3061313e565b6119aa612e57565b8151604080519182526001600160a01b038e811660208401528282018e9052606083018d90528b8116608084015260a083018b905260c083018a905260e0830189905290519216917fb3a36ac05090f711e42b60c13a82d445eeea0e6aa81bb29143354d10f02de515918190036101000190a251915050611a2b6001600055565b98975050505050505050565b6001546001600160a01b0316611a4b612e57565b6001600160a01b031614611a725760405163e0305dbd60e01b815260040160405180910390fd5b60405163785f6df160e11b8152600481018290526001600160a01b0383169063f0bedbe290602401600060405180830381600087803b158015611ab457600080fd5b505af1158015611ac8573d6000803e3d6000fd5b505050505050565b600b60205281600052604060002081815481106108f357600080fd5b60006001600160a01b03821673d8253782c45a12053594b9deb72d8e8ab2fca54c14806108d157506001600160a01b0382167352ceba41da235af367bfc0b0ccd3314cb901bb5f1492915050565b611b42612e2d565b600082815260086020526040902080548314611b715760405163385f723560e11b815260040160405180910390fd5b600481015460ff16611b96576040516331e52e2f60e11b815260040160405180910390fd5b600f8101546001600160a01b031615611bc257604051634189c8eb60e01b815260040160405180910390fd5b600e81015415611c1157600e8101548214611bf057604051632b0706f360e11b815260040160405180910390fd5b611c0c81600084611bff612e57565b611c07612e57565b6133b9565b611c23565b611c238183611c1e612e57565b61387b565b50611c2e6001600055565b5050565b6001546001600160a01b0316611c46612e57565b6001600160a01b031614611c6d5760405163e0305dbd60e01b815260040160405180910390fd5b60066000846004811115611c8357611c83613eb8565b6004811115611c9457611c94613eb8565b815260208101919091526040016000205415611cc3576040516327b85cbd60e11b815260040160405180910390fd5b60405180606001604052806202a30042611cdd91906143f4565b81526001600160a01b038416602082015260400182905260066000856004811115611d0a57611d0a613eb8565b6004811115611d1b57611d1b613eb8565b8152602080820192909252604090810160002083518155918301516001830180546001600160a01b0319166001600160a01b0390921691909117905591909101516002909101557f86496aa80f046dc4404f94bce44e24d8e17dc1bb123e8c774ff23ce0e6f0aabe836004811115611d9557611d95613eb8565b8383604051611da693929190614090565b60405180910390a1505050565b600860208181526000928352604092839020805460018083015460028401546003850154600486015460058701548a5160808082018d5260068a0154825260078a0154828c01529a890154818d0152600989015460608201528b519a8b01909b52600a880180546001600160a01b038181168d52989c9689169b9590981699939860ff938416989297909594919391850192600160a01b900490911690811115611e5f57611e5f613eb8565b6001811115611e7057611e70613eb8565b8152600182015460208083019190915260029092015460409182015280518082018252600d8501546001600160a01b039081168252600e860154828501528251608081018452600f870154909116815260108601549381019390935260118501549183019190915260129093015460608201529091908a565b611ef1612e2d565b6000818152601360205260409020544290611f109062015180906143f4565b10611f2e5760405163459b792d60e11b815260040160405180910390fd5b6000818152601260205260408120549003611f5c57604051630ebe58ef60e11b815260040160405180910390fd5b60008181526012602052604081208054611f7890600190614407565b81548110611f8857611f8861441a565b600091825260208083209091015480835260109091526040822080549193509103611fc657604051630dcea1fb60e31b815260040160405180910390fd5b600481015460ff16611feb57604051634f98164160e11b815260040160405180910390fd5b8281600101541461200f57604051630c17e23d60e31b815260040160405180910390fd5b6000838152600860205260409020612025612e57565b60018201546001600160a01b039081169116146120555760405163632e534d60e01b815260040160405180910390fd5b600481015460ff1661207a576040516331e52e2f60e11b815260040160405180910390fd5b6003820154600e820181905560028301546120a491839186919030906001600160a01b03166133b9565b60028201546001600160a01b031660009081526011602090815260408083208454845290915281205560048201805460ff191690556120e1612e57565b6001600160a01b03167f493e1e7f0e9233f36d4697a11b43b59a1507e08e3c1f920549858785646ac179858460000154604051612128929190918252602082015260400190565b60405180910390a2505050610b996001600055565b612145612e2d565b6000818152600860205260409020805482146121745760405163385f723560e11b815260040160405180910390fd5b61217c612e57565b60018201546001600160a01b039081169116146121ac5760405163632e534d60e01b815260040160405180910390fd5b600f8101546001600160a01b0316156121d857604051634189c8eb60e01b815260040160405180910390fd5b600481015460ff166121fd576040516331e52e2f60e11b815260040160405180910390fd5b6040805161014081018252825481526001808401546001600160a01b0390811660208085019190915260028601548216848601526003860154606080860191909152600487015460ff9081161515608080880191909152600589015460a08801528751808201895260068a0154815260078a01548186015260088a0154818a015260098a01549381019390935260c08701929092528651918201909652600a87018054938416825261236496889560e08801959394929392850192600160a01b9004909116908111156122d2576122d2613eb8565b60018111156122e3576122e3613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f860154909116815260108501549181019190915260118401548183015260129093015460608401520152613b9b565b60018101546001600160a01b03166000908152600c602052604081206123b391600e9060035b600481111561239b5761239b613eb8565b81526020019081526020016000208360000154613c26565b6040805160808101909152600a820180546001600160a01b03811683526124339291906020830190600160a01b900460ff1660018111156123f6576123f6613eb8565b600181111561240757612407613eb8565b8152600182810154602083015260029092015460409091015283015430906001600160a01b031661313e565b61243c826132b7565b60048101805460ff19169055612450612e57565b6001600160a01b03167fa9e0cdf27a7965d21573ebb808fbcb2c2a1cfd656e1ecf3f82549437b47406778360405161248a91815260200190565b60405180910390a250610b996001600055565b600d60205281600052604060002081815481106108f357600080fd5b6001546001600160a01b03166124cd612e57565b6001600160a01b0316146124f45760405163e0305dbd60e01b815260040160405180910390fd5b6004600081815260066020908152604080516060810182527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eed548082527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eee546001600160a01b0316938201939093527fc5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eef5491810191909152849291158061259c575080514211155b156125ba5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b038316156125ff57826001600160a01b031681602001516001600160a01b0316146125ff576040516342b28e8560e01b815260040160405180910390fd5b8115612629578181604001511461262957604051636c72ff3b60e11b815260040160405180910390fd5b6005546040517f709d4a2a735567787a6859678c4b234a262c4355d6d33796ddb4ef59f80c662191612668916001600160a01b0390911690889061446b565b60405180910390a1600580546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b600a60205281600052604060002081815481106108f357600080fd5b601260205281600052604060002081815481106108f357600080fd5b600981815481106126e957600080fd5b600091825260209091200154905081565b60006108d182613c31565b61270d612e2d565b60008181526008602052604090208054821461273c5760405163385f723560e11b815260040160405180910390fd5b612744612e57565b60018201546001600160a01b039081169116146127745760405163632e534d60e01b815260040160405180910390fd5b600f8101546001600160a01b031661279f5760405163c4912b5360e01b815260040160405180910390fd5b600481015460ff166127c4576040516331e52e2f60e11b815260040160405180910390fd5b6127cd816130a2565b60006127d883612e79565b600d8301549091506001600160a01b03166323b872dd6127f6612e57565b600f8501546040516001600160e01b031960e085901b16815261282892916001600160a01b03169086906004016144b5565b6020604051808303816000875af1158015612847573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061286b9190614449565b506040805160808101909152600a830180546001600160a01b03811683526128af9291906020830190600160a01b900460ff1660018111156112cd576112cd613eb8565b6128b8836132b7565b6128c0612e57565b6001600160a01b03167f573152bdc3a6b0ce7d310a9875f49776804dd1634202817985b567975731711f8460405161134f91815260200190565b6001546001600160a01b031661290e612e57565b6001600160a01b0316146129355760405163e0305dbd60e01b815260040160405180910390fd5b6040516317b0dca160e31b8152600481018390526001600160a01b03828116602483015284169063bd86e508906044015b600060405180830381600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b50505050505050565b6001546001600160a01b03166129b1612e57565b6001600160a01b0316146129d85760405163e0305dbd60e01b815260040160405180910390fd5b6001600081815260066020908152604080516060810182527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a31548082527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a32546001600160a01b0316938201939093527f3e5fec24aa4dc4e5aee2e025e51e1392c72a2500577559fae9665c6d52bd6a3354918101919091528492911580612a80575080514211155b15612a9e5760405163cfb1217b60e01b815260040160405180910390fd5b6001600160a01b03831615612ae357826001600160a01b031681602001516001600160a01b031614612ae3576040516342b28e8560e01b815260040160405180910390fd5b8115612b0d5781816040015114612b0d57604051636c72ff3b60e11b815260040160405180910390fd5b6001600160a01b038516612b3457604051635e192a0160e11b815260040160405180910390fd5b6002546040517f0bc21fe5c3ab742ff1d15b5c4477ffbacf1167e618228078fa625edebe7f331d91612b73916001600160a01b0390911690889061446b565b60405180910390a1600280546001600160a01b0319166001600160a01b03871617905560066000856004811115610d8557610d85613eb8565b612bb4613d95565b600082815260086020818152604092839020835161014081018552815481526001808301546001600160a01b039081168386015260028401548116838801526003840154606080850191909152600485015460ff9081161515608080870191909152600587015460a087015289518082018b52600688015481526007880154818a015298870154898b015260098701549289019290925260c08501979097528751908101909752600a8401805491821688529296939560e0880195850192600160a01b9092041690811115612c8b57612c8b613eb8565b6001811115612c9c57612c9c613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f86015490911681526010850154918101919091526011840154818301526012909301546060840152015292915050565b612d5b6040518060a00160405280600081526020016000815260200160006001600160a01b03168152602001600081526020016000151581525090565b50600090815260106020908152604091829020825160a0810184528154815260018201549281019290925260028101546001600160a01b0316928201929092526003820154606082015260049091015460ff161515608082015290565b6000612dc382613c31565b15612dd057506001919050565b612dd98261302d565b15612de657506000919050565b60405162461bcd60e51b8152602060048201526012602482015271151414ce88155b9adb9bdddb88185cdcd95d60721b60448201526064015b60405180910390fd5b919050565b600260005403612e5057604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6000612e6233611aec565b15612e74575060131936013560601c90565b503390565b6000818152600860208181526040808420815161014081018352815481526001808301546001600160a01b039081168387015260028401548116838601526003840154606080850191909152600485015460ff9081161515608080870191909152600587015460a087015287518082018952600688015481526007880154818b0152998701548a8901526009870154928a019290925260c08501989098528551908101909552600a84018054918216865288979396949560e08801959094919390850192600160a01b900490911690811115612f5757612f57613eb8565b6001811115612f6857612f68613eb8565b8152600182015460208083019190915260029092015460409182015291835281518083018352600d8501546001600160a01b039081168252600e86015482840152848301919091528251608081018452600f8601549091168152601085015481830152601185015481840152601290940154606085015291019190915260c082015181015161010083015190910151919250612710916130089190614485565b61301291906144d9565b8161010001516020015161302691906143f4565b9392505050565b6000816001600160a01b03166318160ddd6175306040518263ffffffff1660e01b81526004016020604051808303818786fa9350505050801561308d575060408051601f3d908101601f1916820190925261308a918101906144fb565b60015b61309957506000919050565b50600192915050565b6012810154156130c55760405163ea9883a360e01b815260040160405180910390fd5b60048101805460ff1916905542601282015560018101546001600160a01b03166000908152600c6020526040812061310191600e90600361238a565b600f8101546001600160a01b031615610b9957600f8101546001600160a01b03166000908152600d60205260408120610b9991600e90600461238a565b60008360200151600181111561315657613156613eb8565b0361321f57306001600160a01b038316036131e9578251604080850151905163a9059cbb60e01b81526001600160a01b039092169163a9059cbb916131a091859190600401614430565b6020604051808303816000875af11580156131bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e39190614449565b50505050565b825160408085015190516323b872dd60e01b81526001600160a01b03909216916323b872dd916131a091869186916004016144b5565b60018360200151600181111561323757613237613eb8565b0361327257825160608401516040516323b872dd60e01b81526001600160a01b03909216916323b872dd9161296691869186916004016144b5565b60405162461bcd60e51b81526020600482015260156024820152745450533a2057726f6e67206173736574207479706560581b6044820152606401612e1f565b505050565b600081815260086020526040902060028101546001600160a01b031615611c2e5760028101546001820154600383015460405163a9059cbb60e01b81526001600160a01b039384169363a9059cbb9361331593911691600401614430565b6020604051808303816000875af1158015613334573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b29190614449565b600081815260086020526040902060028101546001600160a01b031615611c2e576002810154600182015460038301546040516323b872dd60e01b81526001600160a01b03938416936323b872dd93613315939116913091906004016144b5565b6000612710600354856133cc9190614485565b6133d691906144d9565b905060006133e48286614407565b9050306001600160a01b0385160361347957600d870154600188015460405163a9059cbb60e01b81526001600160a01b039283169263a9059cbb92613430929116908590600401614430565b6020604051808303816000875af115801561344f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134739190614449565b50613575565b600d87015460018801546040516323b872dd60e01b81526001600160a01b03928316926323b872dd926134b69289929091169086906004016144b5565b6020604051808303816000875af11580156134d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f99190614449565b50600d8701546040516323b872dd60e01b81526001600160a01b03909116906323b872dd90613530908790309087906004016144b5565b6020604051808303816000875af115801561354f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135739190614449565b505b600d87015461358d906001600160a01b031683613caf565b8287600f0160000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055504387600f01600101819055504287600f01600201819055506137178760405180610140016040529081600082015481526020016001820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016002820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600382015481526020016004820160009054906101000a900460ff1615151515815260200160058201548152602001600682016040518060800160405290816000820154815260200160018201548152602001600282015481526020016003820154815250508152602001600a82016040518060800160405290816000820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b031681526020016000820160149054906101000a900460ff1660018111156122d2576122d2613eb8565b6001600160a01b0383166000818152600d6020908152604082208a5481546001818101845583865293852001559290915290546137549190614407565b875460009081527fa1d6913cd9e08c872be3e7525cca82e4fc0fc298a783f19022be725b19be685a602052604081209190915560068801549003613819576040805160808101909152600a880180546001600160a01b03811683526138059291906020830190600160a01b900460ff1660018111156137d5576137d5613eb8565b60018111156137e6576137e6613eb8565b815260200160018201548152602001600282015481525050308561313e565b8654613810906132b7565b613819876130a2565b8654604080519182526020820188905281018690526001600160a01b038086166060830152841660808201527fb4a7227fb0dfeb98811f5d56165a8829f9656773c1b9dc94821d75c46f42f7639060a00160405180910390a150505050505050565b6001600160a01b038116600090815260116020908152604080832086548452909152902054156138be5760405163aca2258560e01b815260040160405180910390fd5b82600501548210156138e3576040516304f3be9f60e11b815260040160405180910390fd5b8254600090815260126020526040902054156139c9578254600090815260136020526040902054429061391a9062015180906143f4565b116139385760405163a508237960e01b815260040160405180910390fd5b82546000908152601260205260408120805461395690600190614407565b815481106139665761396661441a565b9060005260206000200154905060006010600083815260200190815260200160002090508360648260030154606e61399e9190614485565b6139a891906144d9565b106139c65760405163066881a960e51b815260040160405180910390fd5b50505b6040805160a081018252600f548152845460208083018290526001600160a01b038086168486018190526060850188905260016080860181905260009485526012845286852086518154928301825590865284862090910155885480855286852054918552601184528685209085529092529390912055600d8501549091166323b872dd613a55612e57565b30866040518463ffffffff1660e01b8152600401613a75939291906144b5565b6020604051808303816000875af1158015613a94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab89190614449565b50835460009081526013602090815260408083204290558351835260108252808320845181559184015160018301558301516002820180546001600160a01b0319166001600160a01b039092169190911790556060830151600382015560808301516004909101805460ff1916911515919091179055600f805491613b3c8361449c565b90915550508354815160408051928352602083019190915281018490526001600160a01b03831660608201527f212de920a843943385be4d0be6f5375802a6c0eb13258959f94184f8599aa1f19060800160405180910390a150505050565b613bcf6009600e6000805b6004811115613bb757613bb7613eb8565b81526020019081526020016000208360000151613c26565b60e0810151516001600160a01b03166000908152600a60205260408120613bfa91600e906001613ba6565b610100810151516001600160a01b03166000908152600b60205260408120610b9991600e906002613ba6565b6132b2838383613cef565b6000816001600160a01b03166301ffc9a76175306380ac58cd60e01b6040518363ffffffff1660e01b8152600401613c699190614033565b6020604051808303818786fa93505050508015613ca3575060408051601f3d908101601f19168201909252613ca091810190614449565b60015b6108d157506000919050565b80600003613cbb575050565b60025460405163a9059cbb60e01b81526001600160a01b038481169263a9059cbb9261331592909116908590600401614430565b82546000908490613d0290600190614407565b81548110613d1257613d1261441a565b600091825260208083209091015484835290859052604080832080548385529184208290559285905260001990925585549092508290869083908110613d5a57613d5a61441a565b906000526020600020018190555084805480613d7857613d78614514565b600190038181906000526020600020016000905590555050505050565b6040518061014001604052806000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160001515815260200160008152602001613e0a6040518060800160405280600081526020016000815260200160008152602001600081525090565b81526040805160808101825260008082526020808301829052828401829052606083018290528085019290925282518084018452818152918201529101908152602001613e81604051806080016040528060006001600160a01b031681526020016000815260200160008152602001600081525090565b905290565b80356001600160a01b0381168114612e2857600080fd5b600060208284031215613eaf57600080fd5b61302682613e86565b634e487b7160e01b600052602160045260246000fd5b60028110613eec57634e487b7160e01b600052602160045260246000fd5b9052565b602081016108d18284613ece565b60008060408385031215613f1157600080fd5b613f1a83613e86565b946020939093013593505050565b600060208284031215613f3a57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215613f6d57600080fd5b613f7685613e86565b9350613f8460208601613e86565b925060408501359150606085013567ffffffffffffffff80821115613fa857600080fd5b818701915087601f830112613fbc57600080fd5b813581811115613fce57613fce613f41565b604051601f8201601f19908116603f01168101908382118183101715613ff657613ff6613f41565b816040528281528a602084870101111561400f57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6001600160e01b031991909116815260200190565b60058110610b9957600080fd5b6000806040838503121561406857600080fd5b8235613f1a81614048565b60006020828403121561408557600080fd5b813561302681614048565b9283526001600160a01b03919091166020830152604082015260600190565b600080600080600080600080610100898b0312156140cc57600080fd5b6140d589613e86565b975060208901359650604089013595506140f160608a01613e86565b979a969950949760808101359660a0820135965060c0820135955060e0909101359350915050565b6000806040838503121561412c57600080fd5b50508035926020909101359150565b60008060006060848603121561415057600080fd5b833561415b81614048565b925061416960208501613e86565b9150604084013590509250925092565b805182526020810151602083015260408101516040830152606081015160608301525050565b80516001600160a01b03168252602080820151906141bf90840182613ece565b5060408181015190830152606090810151910152565b80516001600160a01b03168252602090810151910152565b80516001600160a01b031682526020808201519083015260408082015190830152606090810151910152565b8a81526001600160a01b038a811660208301528916604082015260608101889052861515608082015260a08101869052610280810161425b60c0830187614179565b61426961014083018661419f565b6142776101c08301856141d5565b6142856102008301846141ed565b9b9a5050505050505050505050565b6000806000606084860312156142a957600080fd5b6142b284613e86565b9250602084013591506142c760408501613e86565b90509250925092565b815181526020808301516102808301916142f4908401826001600160a01b03169052565b50604083015161430f60408401826001600160a01b03169052565b5060608301516060830152608083015161432d608084018215159052565b5060a083015160a083015260c083015161434a60c0840182614179565b5060e083015161435e61014084018261419f565b506101008301516143736101c08401826141d5565b506101208301516143886102008401826141ed565b5092915050565b60006020808352835180602085015260005b818110156143bd578581018301518582016040015282016143a1565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b808201808211156108d1576108d16143de565b818103818111156108d1576108d16143de565b634e487b7160e01b600052603260045260246000fd5b6001600160a01b03929092168252602082015260400190565b60006020828403121561445b57600080fd5b8151801515811461302657600080fd5b6001600160a01b0392831681529116602082015260400190565b80820281158282048414176108d1576108d16143de565b6000600182016144ae576144ae6143de565b5060010190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6000826144f657634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561450d57600080fd5b5051919050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d25f358537997ae8171a8b21f2a548812a45b87cd8b9376ce9e8e3ed7c0f80ec64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a940000000000000000000000007ad5935ea295c4e743e4f2f5b4cda951f41223c20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a94
-----Decoded View---------------
Arg [0] : _owner (address): 0xbbbbb8C4364eC2ce52c59D2Ed3E56F307E529a94
Arg [1] : _depositToken (address): 0x7AD5935EA295c4E743e4f2f5B4CDA951f41223c2
Arg [2] : _positionDepositAmount (uint256): 1000000000000000000
Arg [3] : _feeRecipient (address): 0xbbbbb8C4364eC2ce52c59D2Ed3E56F307E529a94
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a94
Arg [1] : 0000000000000000000000007ad5935ea295c4e743e4f2f5b4cda951f41223c2
Arg [2] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [3] : 000000000000000000000000bbbbb8c4364ec2ce52c59d2ed3e56f307e529a94
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.