Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 35 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Hourly ... | 17423750 | 584 days ago | IN | 0 ETH | 0.005469 | ||||
Withdraw Hourly ... | 17423744 | 584 days ago | IN | 0 ETH | 0.00464165 | ||||
Withdraw Hourly ... | 14892358 | 953 days ago | IN | 0 ETH | 0.01056015 | ||||
Buy Hourly Bond ... | 14889807 | 954 days ago | IN | 0 ETH | 0.01226532 | ||||
Withdraw Hourly ... | 14620502 | 997 days ago | IN | 0 ETH | 0.00515815 | ||||
Buy Hourly Bond ... | 14616885 | 997 days ago | IN | 0 ETH | 0.00899899 | ||||
Buy Hourly Bond ... | 14486784 | 1018 days ago | IN | 0 ETH | 0.00645993 | ||||
Buy Hourly Bond ... | 14354197 | 1038 days ago | IN | 0 ETH | 0.00844431 | ||||
Withdraw Hourly ... | 14349719 | 1039 days ago | IN | 0 ETH | 0.00425886 | ||||
Withdraw Hourly ... | 14131481 | 1073 days ago | IN | 0 ETH | 0.01137733 | ||||
Buy Hourly Bond ... | 14112000 | 1076 days ago | IN | 0 ETH | 0.01538167 | ||||
Withdraw Hourly ... | 13706196 | 1139 days ago | IN | 0 ETH | 0.01077411 | ||||
Buy Hourly Bond ... | 13497236 | 1172 days ago | IN | 0 ETH | 0.02523382 | ||||
Buy Hourly Bond ... | 13492278 | 1173 days ago | IN | 0 ETH | 0.00899364 | ||||
Withdraw Hourly ... | 13492078 | 1173 days ago | IN | 0 ETH | 0.0141771 | ||||
Buy Hourly Bond ... | 13461509 | 1177 days ago | IN | 0 ETH | 0.01454083 | ||||
Withdraw Hourly ... | 13454762 | 1179 days ago | IN | 0 ETH | 0.00642444 | ||||
Withdraw Hourly ... | 13454628 | 1179 days ago | IN | 0 ETH | 0.00701428 | ||||
Withdraw Hourly ... | 13454365 | 1179 days ago | IN | 0 ETH | 0.00813925 | ||||
Buy Hourly Bond ... | 13351887 | 1195 days ago | IN | 0 ETH | 0.00837734 | ||||
Withdraw Hourly ... | 13261665 | 1209 days ago | IN | 0 ETH | 0.00566724 | ||||
Withdraw Hourly ... | 13229807 | 1214 days ago | IN | 0 ETH | 0.005066 | ||||
Withdraw Hourly ... | 13229752 | 1214 days ago | IN | 0 ETH | 0.00394728 | ||||
Withdraw Hourly ... | 13222196 | 1215 days ago | IN | 0 ETH | 0.00485901 | ||||
Buy Hourly Bond ... | 13106509 | 1233 days ago | IN | 0 ETH | 0.01072071 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
Lending
Compiler Version
v0.8.3+commit.8d00100c
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Fund.sol"; import "./HourlyBondSubscriptionLending.sol"; import "../libraries/IncentiveReporter.sol"; // TODO activate bonds for lending /// @title Manage lending for a variety of bond issuers contract Lending is RoleAware, HourlyBondSubscriptionLending { /// mapping issuers to tokens /// (in crossmargin, the issuers are tokens themselves) mapping(address => address) public issuerTokens; /// In case of shortfall, adjust debt mapping(address => uint256) public haircuts; /// map of available issuers mapping(address => bool) public activeIssuers; uint256 constant BORROW_RATE_UPDATE_WINDOW = 60 minutes; address public immutable MFI; constructor(address _MFI, address _roles) RoleAware(_roles) { MFI = _MFI; } /// Make a issuer available for protocol function activateIssuer(address issuer) external { activateIssuer(issuer, issuer); } /// Make issuer != token available for protocol (isol. margin) function activateIssuer(address issuer, address token) public onlyOwnerExecActivator { activeIssuers[issuer] = true; issuerTokens[issuer] = token; } /// Remove a issuer from trading availability function deactivateIssuer(address issuer) external onlyOwnerExecActivator { activeIssuers[issuer] = false; } /// Set lending cap function setLendingCap(address issuer, uint256 cap) external onlyOwnerExecActivator { lendingMeta[issuer].lendingCap = cap; } /// Set withdrawal window function setWithdrawalWindow(uint256 window) external onlyOwnerExec { withdrawalWindow = window; } function setNormalRatePerPercent(uint256 rate) external onlyOwnerExec { normalRatePerPercent = rate; } function setHighRatePerPercent(uint256 rate) external onlyOwnerExec { highRatePerPercent = rate; } /// Set hourly yield APR for issuer function setHourlyYieldAPR(address issuer, uint256 aprPercent) external onlyOwnerExecActivator { YieldAccumulator storage yieldAccumulator = hourlyBondYieldAccumulators[issuer]; if (yieldAccumulator.accumulatorFP == 0) { uint256 yieldFP = FP48 + (FP48 * aprPercent) / 100 / (24 * 365); hourlyBondYieldAccumulators[issuer] = YieldAccumulator({ accumulatorFP: FP48, lastUpdated: block.timestamp, hourlyYieldFP: yieldFP }); } else { YieldAccumulator storage yA = getUpdatedHourlyYield( issuer, yieldAccumulator, RATE_UPDATE_WINDOW ); yA.hourlyYieldFP = (FP48 * (100 + aprPercent)) / 100 / (24 * 365); } } /// @dev how much interest has accrued to a borrowed balance over time function applyBorrowInterest( uint256 balance, address issuer, uint256 yieldQuotientFP ) external returns (uint256 balanceWithInterest, uint256 accumulatorFP) { require(isBorrower(msg.sender), "Not approved call"); YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; updateBorrowYieldAccu(yA); accumulatorFP = yA.accumulatorFP; balanceWithInterest = applyInterest( balance, accumulatorFP, yieldQuotientFP ); uint256 deltaAmount = balanceWithInterest - balance; LendingMetadata storage meta = lendingMeta[issuer]; meta.totalBorrowed += deltaAmount; } /// @dev view function to get balance with borrowing interest applied function viewWithBorrowInterest( uint256 balance, address issuer, uint256 yieldQuotientFP ) external view returns (uint256) { uint256 accumulatorFP = viewCumulativeYieldFP( borrowYieldAccumulators[issuer], block.timestamp ); return applyInterest(balance, accumulatorFP, yieldQuotientFP); } /// @dev gets called by router to register if a trader borrows issuers function registerBorrow(address issuer, uint256 amount) external { require(isBorrower(msg.sender), "Not approved borrower"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; meta.totalBorrowed += amount; getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], BORROW_RATE_UPDATE_WINDOW ); require( meta.totalLending >= meta.totalBorrowed, "Insufficient lending" ); } /// @dev gets called when external sources provide lending function registerLend(address issuer, uint256 amount) external { require(isLender(msg.sender), "Not an approved lender"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; addToTotalLending(meta, amount); getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); } /// @dev gets called when external sources pay withdraw their bobnd function registerWithdrawal(address issuer, uint256 amount) external { require(isLender(msg.sender), "Not an approved lender"); require(activeIssuers[issuer], "Not approved issuer"); LendingMetadata storage meta = lendingMeta[issuer]; subtractFromTotalLending(meta, amount); getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); } /// @dev gets called by router if loan is extinguished function payOff(address issuer, uint256 amount) external { require(isBorrower(msg.sender), "Not approved borrower"); lendingMeta[issuer].totalBorrowed -= amount; } /// @dev get the borrow yield for a specific issuer/token function viewAccumulatedBorrowingYieldFP(address issuer) external view returns (uint256) { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; return viewCumulativeYieldFP(yA, block.timestamp); } function viewAPRPer10k(YieldAccumulator storage yA) internal view returns (uint256) { uint256 hourlyYieldFP = yA.hourlyYieldFP; uint256 aprFP = ((hourlyYieldFP * 10_000 - FP48 * 10_000) * 365 days) / (1 hours); return aprFP / FP48; } /// @dev get current borrowing interest per 10k for a token / issuer function viewBorrowAPRPer10k(address issuer) external view returns (uint256) { return viewAPRPer10k(borrowYieldAccumulators[issuer]); } /// @dev get current lending APR per 10k for a token / issuer function viewHourlyBondAPRPer10k(address issuer) external view returns (uint256) { return viewAPRPer10k(hourlyBondYieldAccumulators[issuer]); } /// @dev In a liquidity crunch make a fallback bond until liquidity is good again function makeFallbackBond( address issuer, address holder, uint256 amount ) external { require(isLender(msg.sender), "Not an approved lender"); _makeHourlyBond(issuer, holder, amount); } /// @dev withdraw an hour bond function withdrawHourlyBond(address issuer, uint256 amount) external { HourlyBond storage bond = hourlyBondAccounts[issuer][msg.sender]; super._withdrawHourlyBond(issuer, bond, amount, msg.sender); if (bond.amount == 0) { delete hourlyBondAccounts[issuer][msg.sender]; } disburse(issuer, msg.sender, amount); IncentiveReporter.subtractFromClaimAmount(issuer, msg.sender, amount); } /// Shut down hourly bond account for `issuer` function closeHourlyBondAccount(address issuer) external { HourlyBond storage bond = hourlyBondAccounts[issuer][msg.sender]; uint256 amount = bond.amount; super._withdrawHourlyBond(issuer, bond, amount, msg.sender); disburse(issuer, msg.sender, amount); delete hourlyBondAccounts[issuer][msg.sender]; IncentiveReporter.subtractFromClaimAmount(issuer, msg.sender, amount); } /// @dev buy hourly bond subscription function buyHourlyBondSubscription(address issuer, uint256 amount) external { require(activeIssuers[issuer], "Not approved issuer"); collectToken(issuer, msg.sender, amount); super._makeHourlyBond(issuer, msg.sender, amount); IncentiveReporter.addToClaimAmount(issuer, msg.sender, amount); } function initBorrowYieldAccumulator(address issuer) external onlyOwnerExecActivator { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; require(yA.accumulatorFP == 0, "don't re-initialize"); yA.accumulatorFP = FP48; yA.lastUpdated = block.timestamp; yA.hourlyYieldFP = FP48 + (FP48 * borrowMinAPR) / 1000 / (365 * 24); } function setBorrowingFactorPercent(uint256 borrowingFactor) external onlyOwnerExec { borrowingFactorPercent = borrowingFactor; } function issuanceBalance(address issuer) internal view override returns (uint256) { address token = issuerTokens[issuer]; if (token == issuer) { // cross margin return IERC20(token).balanceOf(fund()); } else { return lendingMeta[issuer].totalLending - haircuts[issuer]; } } function disburse( address issuer, address recipient, uint256 amount ) internal { uint256 haircutAmount = haircuts[issuer]; if (haircutAmount > 0 && amount > 0) { uint256 totalLending = lendingMeta[issuer].totalLending; uint256 adjustment = (amount * min(totalLending, haircutAmount)) / totalLending; amount = amount - adjustment; haircuts[issuer] -= adjustment; } address token = issuerTokens[issuer]; Fund(fund()).withdraw(token, recipient, amount); } function collectToken( address issuer, address source, uint256 amount ) internal { Fund(fund()).depositFor(source, issuerTokens[issuer], amount); } function haircut(uint256 amount) external { haircuts[msg.sender] += amount; } function addIncentive( address token, uint256 amount, uint256 endTimestamp ) external onlyOwnerExecActivator { LendingMetadata storage meta = lendingMeta[token]; meta.incentiveEnd = endTimestamp; meta.incentiveTarget = amount; meta.incentiveLastUpdated = block.timestamp; } function disburseIncentive( HourlyBond storage bond, LendingMetadata storage meta, address holder ) internal override { uint256 allocationDelta = meta.cumulIncentiveAllocationFP - bond.incentiveAllocationStart; if (allocationDelta > 0) { uint256 disburseAmount = (allocationDelta * bond.amount) / FP48; Fund(fund()).withdraw(MFI, holder, disburseAmount); bond.incentiveAllocationStart += allocationDelta; } } function withdrawIncentive(address token) external { LendingMetadata storage meta = lendingMeta[token]; updateIncentiveAllocation(meta); disburseIncentive( hourlyBondAccounts[token][msg.sender], meta, msg.sender ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// 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 "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./RoleAware.sol"; /// @title Base lending behavior abstract contract BaseLending { uint256 constant FP48 = 2**48; uint256 constant ACCUMULATOR_INIT = 10**18; uint256 constant hoursPerYear = 365 days / (1 hours); uint256 constant CHANGE_POINT = 82; uint256 public normalRatePerPercent = (FP48 * 12) / hoursPerYear / CHANGE_POINT / 100; uint256 public highRatePerPercent = (FP48 * (135 - 12)) / hoursPerYear / (100 - CHANGE_POINT) / 100; struct YieldAccumulator { uint256 accumulatorFP; uint256 lastUpdated; uint256 hourlyYieldFP; } struct LendingMetadata { uint256 totalLending; uint256 totalBorrowed; uint256 lendingCap; uint256 cumulIncentiveAllocationFP; uint256 incentiveLastUpdated; uint256 incentiveEnd; uint256 incentiveTarget; } mapping(address => LendingMetadata) public lendingMeta; /// @dev accumulate interest per issuer (like compound indices) mapping(address => YieldAccumulator) public borrowYieldAccumulators; /// @dev simple formula for calculating interest relative to accumulator function applyInterest( uint256 balance, uint256 accumulatorFP, uint256 yieldQuotientFP ) internal pure returns (uint256) { // 1 * FP / FP = 1 return (balance * accumulatorFP) / yieldQuotientFP; } function currentLendingRateFP(uint256 totalLending, uint256 totalBorrowing) internal view returns (uint256 rate) { rate = FP48; uint256 utilizationPercent = totalLending > 0 ? (100 * totalBorrowing) / totalLending : 0; if (utilizationPercent < CHANGE_POINT) { rate += utilizationPercent * normalRatePerPercent; } else { rate += CHANGE_POINT * normalRatePerPercent + (utilizationPercent - CHANGE_POINT) * highRatePerPercent; } } /// @dev minimum function min(uint256 a, uint256 b) internal pure returns (uint256) { if (a > b) { return b; } else { return a; } } /// @dev maximum function max(uint256 a, uint256 b) internal pure returns (uint256) { if (a > b) { return a; } else { return b; } } /// Available tokens to this issuance function issuanceBalance(address issuance) internal view virtual returns (uint256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../interfaces/IWETH.sol"; import "./RoleAware.sol"; /// @title Manage funding contract Fund is RoleAware { using SafeERC20 for IERC20; /// wrapped ether address public immutable WETH; constructor(address _WETH, address _roles) RoleAware(_roles) { WETH = _WETH; } /// Deposit an active token function deposit(address depositToken, uint256 depositAmount) external { IERC20(depositToken).safeTransferFrom( msg.sender, address(this), depositAmount ); } /// Deposit token on behalf of `sender` function depositFor( address sender, address depositToken, uint256 depositAmount ) external { require(isFundTransferer(msg.sender), "Unauthorized deposit"); IERC20(depositToken).safeTransferFrom( sender, address(this), depositAmount ); } /// Deposit to wrapped ether function depositToWETH() external payable { IWETH(WETH).deposit{value: msg.value}(); } // withdrawers role function withdraw( address withdrawalToken, address recipient, uint256 withdrawalAmount ) external { require(isFundTransferer(msg.sender), "Unauthorized withdraw"); IERC20(withdrawalToken).safeTransfer(recipient, withdrawalAmount); } // withdrawers role function withdrawETH(address recipient, uint256 withdrawalAmount) external { require(isFundTransferer(msg.sender), "Unauthorized withdraw"); IWETH(WETH).withdraw(withdrawalAmount); Address.sendValue(payable(recipient), withdrawalAmount); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./BaseLending.sol"; struct HourlyBond { uint256 amount; uint256 yieldQuotientFP; uint256 moduloHour; uint256 incentiveAllocationStart; } /// @title Here we offer subscriptions to auto-renewing hourly bonds /// Funds are locked in for an 50 minutes per hour, while interest rates float abstract contract HourlyBondSubscriptionLending is BaseLending { mapping(address => YieldAccumulator) hourlyBondYieldAccumulators; uint256 constant RATE_UPDATE_WINDOW = 10 minutes; uint256 public withdrawalWindow = 20 minutes; uint256 constant MAX_HOUR_UPDATE = 4; // issuer => holder => bond record mapping(address => mapping(address => HourlyBond)) public hourlyBondAccounts; uint256 public borrowingFactorPercent = 200; uint256 constant borrowMinAPR = 25; uint256 constant borrowMinHourlyYield = FP48 + (borrowMinAPR * FP48) / 1000 / hoursPerYear; function _makeHourlyBond( address issuer, address holder, uint256 amount ) internal { HourlyBond storage bond = hourlyBondAccounts[issuer][holder]; LendingMetadata storage meta = lendingMeta[issuer]; addToTotalLending(meta, amount); updateHourlyBondAmount(issuer, bond, holder); if (bond.amount == 0) { bond.moduloHour = block.timestamp % (1 hours); } bond.amount += amount; } function updateHourlyBondAmount( address issuer, HourlyBond storage bond, address holder ) internal { uint256 yieldQuotientFP = bond.yieldQuotientFP; YieldAccumulator storage yA = getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ); LendingMetadata storage meta = lendingMeta[issuer]; if (yieldQuotientFP > 0) { disburseIncentive(bond, meta, holder); uint256 oldAmount = bond.amount; bond.amount = applyInterest( bond.amount, yA.accumulatorFP, yieldQuotientFP ); uint256 deltaAmount = bond.amount - oldAmount; addToTotalLending(meta, deltaAmount); } else { bond.incentiveAllocationStart = meta.cumulIncentiveAllocationFP; } bond.yieldQuotientFP = yA.accumulatorFP; } // Retrieves bond balance for issuer and holder function viewHourlyBondAmount(address issuer, address holder) public view returns (uint256) { HourlyBond storage bond = hourlyBondAccounts[issuer][holder]; uint256 yieldQuotientFP = bond.yieldQuotientFP; uint256 cumulativeYield = viewCumulativeYieldFP( hourlyBondYieldAccumulators[issuer], block.timestamp ); if (yieldQuotientFP > 0) { return applyInterest(bond.amount, cumulativeYield, yieldQuotientFP); } else { return bond.amount; } } function _withdrawHourlyBond( address issuer, HourlyBond storage bond, uint256 amount, address holder ) internal { subtractFromTotalLending(lendingMeta[issuer], amount); updateHourlyBondAmount(issuer, bond, holder); // how far the current hour has advanced (relative to acccount hourly clock) uint256 currentOffset = (block.timestamp - bond.moduloHour) % (1 hours); require( withdrawalWindow >= currentOffset, "Tried withdrawing outside subscription cancellation time window" ); bond.amount -= amount; } function calcCumulativeYieldFP( YieldAccumulator storage yieldAccumulator, uint256 timeDelta ) internal view returns (uint256 accumulatorFP) { uint256 secondsDelta = timeDelta % (1 hours); // linearly interpolate interest for seconds // FP * FP * 1 / (FP * 1) = FP accumulatorFP = yieldAccumulator.accumulatorFP + (yieldAccumulator.accumulatorFP * (yieldAccumulator.hourlyYieldFP - FP48) * secondsDelta) / (FP48 * 1 hours); uint256 hoursDelta = timeDelta / (1 hours); if (hoursDelta > 0) { uint256 accumulatorBeforeFP = accumulatorFP; for (uint256 i = 0; hoursDelta > i && MAX_HOUR_UPDATE > i; i++) { // FP48 * FP48 / FP48 = FP48 accumulatorFP = (accumulatorFP * yieldAccumulator.hourlyYieldFP) / FP48; } // a lot of time has passed if (hoursDelta > MAX_HOUR_UPDATE) { // apply interest in non-compounding way accumulatorFP += ((accumulatorFP - accumulatorBeforeFP) * (hoursDelta - MAX_HOUR_UPDATE)) / MAX_HOUR_UPDATE; } } } /// @dev updates yield accumulators for both borrowing and lending /// issuer address represents a token function updateHourlyYield(address issuer) public returns (uint256 hourlyYield) { return getUpdatedHourlyYield( issuer, hourlyBondYieldAccumulators[issuer], RATE_UPDATE_WINDOW ) .hourlyYieldFP; } /// @dev updates yield accumulators for both borrowing and lending function getUpdatedHourlyYield( address issuer, YieldAccumulator storage accumulator, uint256 window ) internal returns (YieldAccumulator storage) { uint256 lastUpdated = accumulator.lastUpdated; uint256 timeDelta = (block.timestamp - lastUpdated); if (timeDelta > window) { YieldAccumulator storage borrowAccumulator = borrowYieldAccumulators[issuer]; accumulator.accumulatorFP = calcCumulativeYieldFP( accumulator, timeDelta ); LendingMetadata storage meta = lendingMeta[issuer]; accumulator.hourlyYieldFP = currentLendingRateFP( meta.totalLending, meta.totalBorrowed ); accumulator.lastUpdated = block.timestamp; updateBorrowYieldAccu(borrowAccumulator); borrowAccumulator.hourlyYieldFP = max( borrowMinHourlyYield, FP48 + (borrowingFactorPercent * (accumulator.hourlyYieldFP - FP48)) / 100 ); } return accumulator; } function updateBorrowYieldAccu(YieldAccumulator storage borrowAccumulator) internal { uint256 timeDelta = block.timestamp - borrowAccumulator.lastUpdated; if (timeDelta > RATE_UPDATE_WINDOW) { borrowAccumulator.accumulatorFP = calcCumulativeYieldFP( borrowAccumulator, timeDelta ); borrowAccumulator.lastUpdated = block.timestamp; } } function getUpdatedBorrowYieldAccuFP(address issuer) external returns (uint256) { YieldAccumulator storage yA = borrowYieldAccumulators[issuer]; updateBorrowYieldAccu(yA); return yA.accumulatorFP; } function viewCumulativeYieldFP( YieldAccumulator storage yA, uint256 timestamp ) internal view returns (uint256) { uint256 timeDelta = (timestamp - yA.lastUpdated); if (timeDelta > RATE_UPDATE_WINDOW) { return calcCumulativeYieldFP(yA, timeDelta); } else { return yA.accumulatorFP; } } function viewYearlyIncentivePer10k(address token) external view returns (uint256) { LendingMetadata storage meta = lendingMeta[token]; if ( meta.incentiveEnd < block.timestamp || meta.incentiveLastUpdated > meta.incentiveEnd ) { return 0; } else { uint256 timeDelta = meta.incentiveEnd - meta.incentiveLastUpdated; // scale to 1 year return (10_000 * (365 days) * meta.incentiveTarget) / (1 + meta.totalLending * timeDelta); } } function updateIncentiveAllocation(LendingMetadata storage meta) internal { uint256 endTime = min(meta.incentiveEnd, block.timestamp); if (meta.incentiveTarget > 0 && endTime > meta.incentiveLastUpdated) { uint256 timeDelta = endTime - meta.incentiveLastUpdated; uint256 targetDelta = min( meta.incentiveTarget, (timeDelta * meta.incentiveTarget) / (meta.incentiveEnd - meta.incentiveLastUpdated) ); meta.incentiveTarget -= targetDelta; meta.cumulIncentiveAllocationFP += (targetDelta * FP48) / (1 + meta.totalLending); meta.incentiveLastUpdated = block.timestamp; } } function addToTotalLending(LendingMetadata storage meta, uint256 amount) internal { updateIncentiveAllocation(meta); meta.totalLending += amount; } function subtractFromTotalLending( LendingMetadata storage meta, uint256 amount ) internal { updateIncentiveAllocation(meta); meta.totalLending -= amount; } function disburseIncentive( HourlyBond storage bond, LendingMetadata storage meta, address holder ) internal virtual; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Roles.sol"; /// @title Role management behavior /// Main characters are for service discovery /// Whereas roles are for access control contract RoleAware { Roles public immutable roles; mapping(uint256 => address) public mainCharacterCache; mapping(address => mapping(uint256 => bool)) public roleCache; constructor(address _roles) { require(_roles != address(0), "Please provide valid roles address"); roles = Roles(_roles); } modifier noIntermediary() { require( msg.sender == tx.origin, "Currently no intermediaries allowed for this function call" ); _; } // @dev Throws if called by any account other than the owner or executor modifier onlyOwnerExec() { require( owner() == msg.sender || executor() == msg.sender, "Roles: caller is not the owner" ); _; } modifier onlyOwnerExecDisabler() { require( owner() == msg.sender || executor() == msg.sender || disabler() == msg.sender, "Caller is not the owner, executor or authorized disabler" ); _; } modifier onlyOwnerExecActivator() { require( owner() == msg.sender || executor() == msg.sender || isTokenActivator(msg.sender), "Caller is not the owner, executor or authorized activator" ); _; } function updateRoleCache(uint256 role, address contr) public virtual { roleCache[contr][role] = roles.getRole(role, contr); } function updateMainCharacterCache(uint256 role) public virtual { mainCharacterCache[role] = roles.mainCharacters(role); } function owner() internal view returns (address) { return roles.owner(); } function executor() internal returns (address) { return roles.executor(); } function disabler() internal view returns (address) { return mainCharacterCache[DISABLER]; } function fund() internal view returns (address) { return mainCharacterCache[FUND]; } function lending() internal view returns (address) { return mainCharacterCache[LENDING]; } function marginRouter() internal view returns (address) { return mainCharacterCache[MARGIN_ROUTER]; } function crossMarginTrading() internal view returns (address) { return mainCharacterCache[CROSS_MARGIN_TRADING]; } function feeController() internal view returns (address) { return mainCharacterCache[FEE_CONTROLLER]; } function price() internal view returns (address) { return mainCharacterCache[PRICE_CONTROLLER]; } function admin() internal view returns (address) { return mainCharacterCache[ADMIN]; } function incentiveDistributor() internal view returns (address) { return mainCharacterCache[INCENTIVE_DISTRIBUTION]; } function tokenAdmin() internal view returns (address) { return mainCharacterCache[TOKEN_ADMIN]; } function isBorrower(address contr) internal view returns (bool) { return roleCache[contr][BORROWER]; } function isFundTransferer(address contr) internal view returns (bool) { return roleCache[contr][FUND_TRANSFERER]; } function isMarginTrader(address contr) internal view returns (bool) { return roleCache[contr][MARGIN_TRADER]; } function isFeeSource(address contr) internal view returns (bool) { return roleCache[contr][FEE_SOURCE]; } function isMarginCaller(address contr) internal view returns (bool) { return roleCache[contr][MARGIN_CALLER]; } function isLiquidator(address contr) internal view returns (bool) { return roleCache[contr][LIQUIDATOR]; } function isAuthorizedFundTrader(address contr) internal view returns (bool) { return roleCache[contr][AUTHORIZED_FUND_TRADER]; } function isIncentiveReporter(address contr) internal view returns (bool) { return roleCache[contr][INCENTIVE_REPORTER]; } function isTokenActivator(address contr) internal view returns (bool) { return roleCache[contr][TOKEN_ACTIVATOR]; } function isStakePenalizer(address contr) internal view returns (bool) { return roleCache[contr][STAKE_PENALIZER]; } function isLender(address contr) internal view returns (bool) { return roleCache[contr][LENDER]; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "../interfaces/IDependencyController.sol"; // we chose not to go with an enum // to make this list easy to extend uint256 constant FUND_TRANSFERER = 1; uint256 constant MARGIN_CALLER = 2; uint256 constant BORROWER = 3; uint256 constant MARGIN_TRADER = 4; uint256 constant FEE_SOURCE = 5; uint256 constant LIQUIDATOR = 6; uint256 constant AUTHORIZED_FUND_TRADER = 7; uint256 constant INCENTIVE_REPORTER = 8; uint256 constant TOKEN_ACTIVATOR = 9; uint256 constant STAKE_PENALIZER = 10; uint256 constant LENDER = 11; uint256 constant FUND = 101; uint256 constant LENDING = 102; uint256 constant MARGIN_ROUTER = 103; uint256 constant CROSS_MARGIN_TRADING = 104; uint256 constant FEE_CONTROLLER = 105; uint256 constant PRICE_CONTROLLER = 106; uint256 constant ADMIN = 107; uint256 constant INCENTIVE_DISTRIBUTION = 108; uint256 constant TOKEN_ADMIN = 109; uint256 constant DISABLER = 1001; uint256 constant DEPENDENCY_CONTROLLER = 1002; /// @title Manage permissions of contracts and ownership of everything /// owned by a multisig wallet (0xEED9D1c6B4cdEcB3af070D85bfd394E7aF179CBd) during /// beta and will then be transfered to governance /// https://github.com/marginswap/governance contract Roles is Ownable { mapping(address => mapping(uint256 => bool)) public roles; mapping(uint256 => address) public mainCharacters; constructor() Ownable() { // token activation from the get-go roles[msg.sender][TOKEN_ACTIVATOR] = true; } /// @dev Throws if called by any account other than the owner. modifier onlyOwnerExecDepController() { require( owner() == msg.sender || executor() == msg.sender || mainCharacters[DEPENDENCY_CONTROLLER] == msg.sender, "Roles: caller is not the owner" ); _; } function giveRole(uint256 role, address actor) external onlyOwnerExecDepController { roles[actor][role] = true; } function removeRole(uint256 role, address actor) external onlyOwnerExecDepController { roles[actor][role] = false; } function setMainCharacter(uint256 role, address actor) external onlyOwnerExecDepController { mainCharacters[role] = actor; } function getRole(uint256 role, address contr) external view returns (bool) { return roles[contr][role]; } /// @dev current executor function executor() public returns (address exec) { address depController = mainCharacters[DEPENDENCY_CONTROLLER]; if (depController != address(0)) { exec = IDependencyController(depController).currentExecutor(); } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IDependencyController { function currentExecutor() external returns (address); }
pragma solidity >=0.5.0; interface IWETH { function deposit() external payable; function transfer(address to, uint256 value) external returns (bool); function withdraw(uint256) external; }
library IncentiveReporter { event AddToClaim(address topic, address indexed claimant, uint256 amount); event SubtractFromClaim( address topic, address indexed claimant, uint256 amount ); /// Start / increase amount of claim function addToClaimAmount( address topic, address recipient, uint256 claimAmount ) internal { emit AddToClaim(topic, recipient, claimAmount); } /// Decrease amount of claim function subtractFromClaimAmount( address topic, address recipient, uint256 subtractAmount ) internal { emit SubtractFromClaim(topic, recipient, subtractAmount); } }
{ "evmVersion": "istanbul", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 5000 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_MFI","type":"address"},{"internalType":"address","name":"_roles","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MFI","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"activateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"activateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"activeIssuers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"endTimestamp","type":"uint256"}],"name":"addIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"}],"name":"applyBorrowInterest","outputs":[{"internalType":"uint256","name":"balanceWithInterest","type":"uint256"},{"internalType":"uint256","name":"accumulatorFP","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowYieldAccumulators","outputs":[{"internalType":"uint256","name":"accumulatorFP","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"hourlyYieldFP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"borrowingFactorPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyHourlyBondSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"closeHourlyBondAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"deactivateIssuer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"getUpdatedBorrowYieldAccuFP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"haircut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"haircuts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"highRatePerPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"hourlyBondAccounts","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"},{"internalType":"uint256","name":"moduloHour","type":"uint256"},{"internalType":"uint256","name":"incentiveAllocationStart","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"initBorrowYieldAccumulator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"issuerTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lendingMeta","outputs":[{"internalType":"uint256","name":"totalLending","type":"uint256"},{"internalType":"uint256","name":"totalBorrowed","type":"uint256"},{"internalType":"uint256","name":"lendingCap","type":"uint256"},{"internalType":"uint256","name":"cumulIncentiveAllocationFP","type":"uint256"},{"internalType":"uint256","name":"incentiveLastUpdated","type":"uint256"},{"internalType":"uint256","name":"incentiveEnd","type":"uint256"},{"internalType":"uint256","name":"incentiveTarget","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mainCharacterCache","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"makeFallbackBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"normalRatePerPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"payOff","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerLend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"registerWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"roleCache","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roles","outputs":[{"internalType":"contract Roles","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"borrowingFactor","type":"uint256"}],"name":"setBorrowingFactorPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setHighRatePerPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"aprPercent","type":"uint256"}],"name":"setHourlyYieldAPR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"setLendingCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setNormalRatePerPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"window","type":"uint256"}],"name":"setWithdrawalWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"updateHourlyYield","outputs":[{"internalType":"uint256","name":"hourlyYield","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"role","type":"uint256"}],"name":"updateMainCharacterCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"role","type":"uint256"},{"internalType":"address","name":"contr","type":"address"}],"name":"updateRoleCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewAccumulatedBorrowingYieldFP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewBorrowAPRPer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"}],"name":"viewHourlyBondAPRPer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"address","name":"holder","type":"address"}],"name":"viewHourlyBondAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"yieldQuotientFP","type":"uint256"}],"name":"viewWithBorrowInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"viewYearlyIncentivePer10k","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"issuer","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawHourlyBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalWindow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c0604052606460526122386200001f6601000000000000600c620001cd565b6200002b9190620001ac565b620000379190620001ac565b620000439190620001ac565b600255606462000055605282620001ef565b6122386200006c6601000000000000607b620001cd565b620000789190620001ac565b620000849190620001ac565b620000909190620001ac565b6003556104b060075560c8600955348015620000ab57600080fd5b5060405162002e9238038062002e92833981016040819052620000ce9162000175565b806001600160a01b038116620001355760405162461bcd60e51b815260206004820152602260248201527f506c656173652070726f766964652076616c696420726f6c6573206164647265604482015261737360f01b606482015260840160405180910390fd5b6001600160601b0319606091821b811660805292901b90911660a052506200021f565b80516001600160a01b03811681146200017057600080fd5b919050565b6000806040838503121562000188578182fd5b620001938362000158565b9150620001a36020840162000158565b90509250929050565b600082620001c857634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620001ea57620001ea62000209565b500290565b60008282101562000204576200020462000209565b500390565b634e487b7160e01b600052601160045260246000fd5b60805160601c60a05160601c612c246200026e6000396000818161079f01526126100152600081816103e50152818161084f01528181610bbe01528181612173015261220b0152612c246000f3fe608060405234801561001057600080fd5b506004361061030a5760003560e01c806391b46e051161019c578063db41039f116100ee578063ed29c12b11610097578063f848767311610071578063f8487673146107e7578063f884614b146107fa578063f90889c91461080d5761030a565b8063ed29c12b1461079a578063ee0862bf146107c1578063f51dfe7a146107d45761030a565b8063e69e2662116100c8578063e69e266214610755578063e9c3f77d1461075e578063ebe64bcc146107875761030a565b8063db41039f14610707578063dc683bcf1461071a578063e695fa681461072d5761030a565b8063cc4b26a311610150578063d19bd0a71161012a578063d19bd0a7146106d8578063d2b48934146106e1578063d4437dd8146106f45761030a565b8063cc4b26a314610668578063cd3b5dfb1461067b578063cfc14f53146106c55761030a565b8063ae4479dd11610181578063ae4479dd1461062f578063b42f60db14610642578063bfdeb719146106555761030a565b806391b46e051461059c578063ad037af6146105af5761030a565b806349d0e2ee1161026057806376668b67116102095780637a009135116101e35780637a009135146104fb5780637a1a04df1461050e57806383a042291461053c5761030a565b806376668b67146104ac57806376c308f2146104bf578063797384b2146104c85761030a565b80636d8d36ba1161023a5780636d8d36ba146104735780636e60e2491461048657806372d01257146104995761030a565b806349d0e2ee1461042d5780634b86daab1461044057806364f85ab1146104535761030a565b806328108026116102c2578063392f5f641161029c578063392f5f64146103e0578063447d52ba1461040757806346c87f801461041a5761030a565b806328108026146103795780632a6a897b146103ba57806336953912146103cd5761030a565b806314189db2116102f357806314189db21461033757806316de7a431461035d578063267031b8146103705761030a565b8063071060a61461030f5780630f7c43dc14610324575b600080fd5b61032261031d366004612a4c565b610820565b005b6103226103323660046129cd565b610917565b61034a610345366004612916565b6109a5565b6040519081526020015b60405180910390f35b61032261036b3660046129cd565b6109d0565b61034a60095481565b6103a2610387366004612916565b600a602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610354565b6103226103c83660046129cd565b610a62565b6103226103db366004612a4c565b610b01565b6103a27f000000000000000000000000000000000000000000000000000000000000000081565b610322610415366004612a64565b610b7f565b61034a610428366004612916565b610c70565b61032261043b366004612a4c565b610c98565b61032261044e366004612916565b610d16565b61034a610461366004612916565b600b6020526000908152604090205481565b6103226104813660046129cd565b610d23565b61034a610494366004612955565b610e44565b61034a6104a7366004612916565b610ebe565b61034a6104ba366004612a88565b610edf565b61034a60025481565b6104eb6104d6366004612916565b600c6020526000908152604090205460ff1681565b6040519015158152602001610354565b610322610509366004612916565b610f19565b6104eb61051c3660046129cd565b600160209081526000928352604080842090915290825290205460ff1681565b61057c61054a366004612955565b600860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610354565b6103226105aa366004612a4c565b610fff565b6105fa6105bd366004612916565b6004602081905260009182526040909120805460018201546002830154600384015494840154600585015460069095015493959294919390919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610354565b61032261063d3660046129cd565b61107d565b6103226106503660046129f8565b611172565b61034a610663366004612916565b611269565b610322610676366004612916565b611301565b6106aa610689366004612916565b60056020526000908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610354565b6103226106d3366004612916565b611480565b61034a60075481565b6103226106ef3660046129cd565b6114d0565b610322610702366004612a4c565b6115b4565b61032261071536600461298d565b6115db565b61034a610728366004612916565b611651565b61074061073b366004612a88565b611681565b60408051928352602083019190915201610354565b61034a60035481565b6103a261076c366004612a4c565b6000602081905290815260409020546001600160a01b031681565b610322610795366004612955565b61176f565b6103a27f000000000000000000000000000000000000000000000000000000000000000081565b6103226107cf3660046129cd565b611891565b61034a6107e2366004612916565b611a12565b6103226107f5366004612a4c565b611a33565b610322610808366004612916565b611ab1565b61032261081b3660046129cd565b611b3a565b6040517fb4ed0b6d000000000000000000000000000000000000000000000000000000008152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b4ed0b6d9060240160206040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190612939565b60009182526020829052604090912080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6001600160a01b03821660009081526008602090815260408083203380855292529091209061094b90849083908590611cfe565b805461098a576001600160a01b038316600090815260086020908152604080832033845290915281208181556001810182905560028101829055600301555b610995833384611de4565b6109a0833384611f6d565b505050565b6001600160a01b03811660009081526005602052604081206109c78142611fb9565b9150505b919050565b6001600160a01b0382166000908152600c602052604090205460ff16610a3d5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f766564206973737565720000000000000000000000000060448201526064015b60405180910390fd5b610a48823383611ffa565b610a538233836120b9565b610a5e82338361212c565b5050565b3360009081526001602090815260408083206003845290915290205460ff16610acd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b03821660009081526004602052604081206001018054839290610af8908490612b17565b90915550505050565b33610b0a61216f565b6001600160a01b03161480610b2e575033610b23612207565b6001600160a01b0316145b610b7a5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600755565b6040517f93552a3d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382811660248301527f000000000000000000000000000000000000000000000000000000000000000016906393552a3d9060440160206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c389190612a2c565b6001600160a01b0391909116600090815260016020908152604080832094835293905291909120805460ff1916911515919091179055565b6001600160a01b0381166000908152600560205260408120610c9181612278565b5492915050565b33610ca161216f565b6001600160a01b03161480610cc5575033610cba612207565b6001600160a01b0316145b610d115760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600355565b610d20818261176f565b50565b336000908152600160209081526040808320600b845290915290205460ff16610d8e5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff16610df65760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e1881836122ac565b6001600160a01b0383166000908152600660205260409020610e3e9084906102586122c9565b50505050565b6001600160a01b038083166000818152600860209081526040808320948616835293815283822060018101549383526006909152928120909291908390610e8b9042611fb9565b90508115610eaa578254610ea09082846123e2565b9350505050610eb8565b5050549050610eb8565b5050505b92915050565b6001600160a01b0381166000908152600660205260408120610eb890612401565b6001600160a01b03821660009081526005602052604081208190610f039042611fb9565b9050610f108582856123e2565b95945050505050565b33610f2261216f565b6001600160a01b03161480610f46575033610f3b612207565b6001600160a01b0316145b80610f6c57503360009081526001602090815260408083206009845290915290205460ff165b610fde5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03166000908152600c60205260409020805460ff19169055565b3361100861216f565b6001600160a01b0316148061102c575033611021612207565b6001600160a01b0316145b6110785760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600955565b336000908152600160209081526040808320600b845290915290205460ff166110e85760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166111505760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e188183612461565b3361117b61216f565b6001600160a01b0316148061119f575033611194612207565b6001600160a01b0316145b806111c557503360009081526001602090815260408083206009845290915290205460ff165b6112375760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b0390921660009081526004602081905260409091206005810193909355600683019190915542910155565b6001600160a01b0381166000908152600460205260408120600581015442118061129a575080600501548160040154115b156112a95760009150506109cb565b6000816004015482600501546112bf9190612b17565b82549091506112cf908290612ada565b6112da906001612aae565b60068301546112ee9064496cebb800612ada565b6112f89190612ac6565b925050506109cb565b3361130a61216f565b6001600160a01b0316148061132e575033611323612207565b6001600160a01b0316145b8061135457503360009081526001602090815260408083206009845290915290205460ff165b6113c65760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b038116600090815260056020526040902080541561142d5760405162461bcd60e51b815260206004820152601360248201527f646f6e27742072652d696e697469616c697a65000000000000000000000000006044820152606401610a34565b6601000000000000808255426001830155612238906103e89061145290601990612ada565b61145c9190612ac6565b6114669190612ac6565b611477906601000000000000612aae565b60029091015550565b6001600160a01b03811660009081526004602052604090206114a18161247e565b6001600160a01b0382166000908152600860209081526040808320338085529252909120610a5e918390612563565b336114d961216f565b6001600160a01b031614806114fd5750336114f2612207565b6001600160a01b0316145b8061152357503360009081526001602090815260408083206009845290915290205460ff165b6115955760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03909116600090815260046020526040902060020155565b336000908152600b6020526040812080548392906115d3908490612aae565b909155505050565b336000908152600160209081526040808320600b845290915290205460ff166116465760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6109a08383836120b9565b6001600160a01b03811660009081526006602052604081206116779083906102586122c9565b6002015492915050565b33600090815260016020908152604080832060038452909152812054819060ff166116ee5760405162461bcd60e51b815260206004820152601160248201527f4e6f7420617070726f7665642063616c6c0000000000000000000000000000006044820152606401610a34565b6001600160a01b038416600090815260056020526040902061170f81612278565b8054915061171e8683866123e2565b9250600061172c8785612b17565b6001600160a01b0387166000908152600460205260408120600181018054939450909284929061175d908490612aae565b92505081905550505050935093915050565b3361177861216f565b6001600160a01b0316148061179c575033611791612207565b6001600160a01b0316145b806117c257503360009081526001602090815260408083206009845290915290205460ff165b6118345760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b039182166000908152600c60209081526040808320805460ff19166001179055600a90915290208054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055565b3360009081526001602090815260408083206003845290915290205460ff166118fc5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166119645760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b038216600090815260046020526040812060018101805491928492611991908490612aae565b90915550506001600160a01b03831660009081526006602052604090206119bc908490610e106122c9565b506001810154815410156109a05760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e74206c656e64696e670000000000000000000000006044820152606401610a34565b6001600160a01b0381166000908152600560205260408120610eb890612401565b33611a3c61216f565b6001600160a01b03161480611a60575033611a55612207565b6001600160a01b0316145b611aac5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600255565b6001600160a01b038116600090815260086020908152604080832033808552925290912080549091611ae890849084908490611cfe565b611af3833383611de4565b6001600160a01b038316600090815260086020908152604080832033808552925282208281556001810183905560028101839055600301919091556109a090849083611f6d565b33611b4361216f565b6001600160a01b03161480611b67575033611b5c612207565b6001600160a01b0316145b80611b8d57503360009081526001602090815260408083206009845290915290205460ff165b611bff5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03821660009081526006602052604090208054611cae5760006122386064611c35856601000000000000612ada565b611c3f9190612ac6565b611c499190612ac6565b611c5a906601000000000000612aae565b60408051606081018252660100000000000081524260208083019182528284019485526001600160a01b038916600090815260069091529290922090518155905160018201559051600290910155506109a0565b6000611cbd84836102586122c9565b90506122386064611cce8582612aae565b611cdf906601000000000000612ada565b611ce99190612ac6565b611cf39190612ac6565b600290910155505050565b6001600160a01b0384166000908152600460205260409020611d2090836122ac565b611d2b848483612699565b6000610e10846002015442611d409190612b17565b611d4a9190612b67565b9050806007541015611dc45760405162461bcd60e51b815260206004820152603f60248201527f5472696564207769746864726177696e67206f7574736964652073756273637260448201527f697074696f6e2063616e63656c6c6174696f6e2074696d652077696e646f77006064820152608401610a34565b82846000016000828254611dd89190612b17565b90915550505050505050565b6001600160a01b0383166000908152600b60205260409020548015801590611e0c5750600082115b15611e8b576001600160a01b0384166000908152600460205260408120549081611e36818561273f565b611e409086612ada565b611e4a9190612ac6565b9050611e568185612b17565b6001600160a01b0387166000908152600b6020526040812080549296508392909190611e83908490612b17565b909155505050505b6001600160a01b038085166000908152600a602052604090205416611ee1606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152868116602483015260448201869052919091169063d9caed1290606401600060405180830381600087803b158015611f4e57600080fd5b505af1158015611f62573d6000803e3d6000fd5b505050505050505050565b604080516001600160a01b038581168252602082018490528416917f3397b60e3ca1e9c0c75a033d62ab8731e9b2937c0690ae5d7f1bd37886b19d7d91015b60405180910390a2505050565b600080836001015483611fcc9190612b17565b9050610258811115611fea57611fe28482612757565b915050610eb8565b50508154610eb8565b5092915050565b7f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b038481166000908152600a60205260408082205481517fb3db428b00000000000000000000000000000000000000000000000000000000815287851660048201529084166024820152604481018690529051929093169263b3db428b926064808301939282900301818387803b15801561209c57600080fd5b505af11580156120b0573d6000803e3d6000fd5b50505050505050565b6001600160a01b038084166000818152600860209081526040808320948716835293815283822092825260049052919091206120f58184612461565b612100858386612699565b815461211857612112610e1042612b67565b60028301555b82826000016000828254611dd89190612aae565b604080516001600160a01b038581168252602082018490528416917f8ec70c9430377a4bba035133e27a5b0f3b9951bc080833f6832bcbbb70a96dba9101611fac565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122029190612939565b905090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561226457600080fd5b505af11580156121de573d6000803e3d6000fd5b600081600101544261228a9190612b17565b9050610258811115610a5e576122a08282612757565b82554260018301555050565b6122b58261247e565b80826000016000828254610af89190612b17565b6001820154600090816122dc8242612b17565b9050838111156123d8576001600160a01b03861660009081526005602052604090206123088683612757565b86556001600160a01b038716600090815260046020526040902080546001820154612333919061286f565b600288015542600188015561234782612278565b6123cd6122386103e861236266010000000000006019612ada565b61236c9190612ac6565b6123769190612ac6565b612387906601000000000000612aae565b606466010000000000008a600201546123a09190612b17565b6009546123ad9190612ada565b6123b79190612ac6565b6123c8906601000000000000612aae565b6128fe565b826002018190555050505b5092949350505050565b6000816123ef8486612ada565b6123f99190612ac6565b949350505050565b600281015460009081610e106124206601000000000000612710612ada565b61242c84612710612ada565b6124369190612b17565b612444906301e13380612ada565b61244e9190612ac6565b90506123f9660100000000000082612ac6565b61246a8261247e565b80826000016000828254610af89190612aae565b600061248e82600501544261273f565b9050600082600601541180156124a75750816004015481115b15610a5e5760008260040154826124be9190612b17565b905060006124fc8460060154856004015486600501546124de9190612b17565b60068701546124ed9086612ada565b6124f79190612ac6565b61273f565b9050808460060160008282546125129190612b17565b90915550508354612524906001612aae565b612535660100000000000083612ada565b61253f9190612ac6565b8460030160008282546125529190612aae565b909155505042600485015550505050565b6000836003015483600301546125799190612b17565b90508015610e3e5783546000906601000000000000906125999084612ada565b6125a39190612ac6565b90506125e0606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152858116602483015260448201849052919091169063d9caed1290606401600060405180830381600087803b15801561266d57600080fd5b505af1158015612681573d6000803e3d6000fd5b5050505081856003016000828254611dd89190612aae565b60018201546001600160a01b03841660009081526006602052604081206126c49086906102586122c9565b6001600160a01b03861660009081526004602052604090209091508215612724576126f0858286612563565b84548254612700908290866123e2565b808755600090612711908390612b17565b905061271d8382612461565b505061272f565b600380820154908601555b5054600190930192909255505050565b600081831115612750575080610eb8565b5081610eb8565b600080612766610e1084612b67565b905061277b6601000000000000610e10612ada565b81660100000000000086600201546127939190612b17565b865461279f9190612ada565b6127a99190612ada565b6127b39190612ac6565b84546127bf9190612aae565b915060006127cf610e1085612ac6565b90508015612867578260005b80831180156127ea5750806004115b156128255766010000000000008760020154866128079190612ada565b6128119190612ac6565b94508061281d81612b2e565b9150506127db565b506004821115610eb457600461283b8184612b17565b6128458387612b17565b61284f9190612ada565b6128599190612ac6565b6128639085612aae565b9350505b505092915050565b660100000000000060008361288557600061289b565b83612891846064612ada565b61289b9190612ac6565b905060528110156128c4576002546128b39082612ada565b6128bd9083612aae565b9150611ff3565b6003546128d2605283612b17565b6128dc9190612ada565b6002546128ea906052612ada565b6128f49190612aae565b6123f99083612aae565b60008183111561290f575081610eb8565b5080610eb8565b600060208284031215612927578081fd5b813561293281612bd9565b9392505050565b60006020828403121561294a578081fd5b815161293281612bd9565b60008060408385031215612967578081fd5b823561297281612bd9565b9150602083013561298281612bd9565b809150509250929050565b6000806000606084860312156129a1578081fd5b83356129ac81612bd9565b925060208401356129bc81612bd9565b929592945050506040919091013590565b600080604083850312156129df578182fd5b82356129ea81612bd9565b946020939093013593505050565b600080600060608486031215612a0c578283fd5b8335612a1781612bd9565b95602085013595506040909401359392505050565b600060208284031215612a3d578081fd5b81518015158114612932578182fd5b600060208284031215612a5d578081fd5b5035919050565b60008060408385031215612a76578182fd5b82359150602083013561298281612bd9565b600080600060608486031215612a9c578283fd5b8335925060208401356129bc81612bd9565b60008219821115612ac157612ac1612b7b565b500190565b600082612ad557612ad5612baa565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b1257612b12612b7b565b500290565b600082821015612b2957612b29612b7b565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612b6057612b60612b7b565b5060010190565b600082612b7657612b76612baa565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6001600160a01b0381168114610d2057600080fdfea26469706673582212208a451470ba8ee8ff877e735ffaac79f28bd8ba5c62f6730bd169f0963e1d946e64736f6c63430008030033000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061030a5760003560e01c806391b46e051161019c578063db41039f116100ee578063ed29c12b11610097578063f848767311610071578063f8487673146107e7578063f884614b146107fa578063f90889c91461080d5761030a565b8063ed29c12b1461079a578063ee0862bf146107c1578063f51dfe7a146107d45761030a565b8063e69e2662116100c8578063e69e266214610755578063e9c3f77d1461075e578063ebe64bcc146107875761030a565b8063db41039f14610707578063dc683bcf1461071a578063e695fa681461072d5761030a565b8063cc4b26a311610150578063d19bd0a71161012a578063d19bd0a7146106d8578063d2b48934146106e1578063d4437dd8146106f45761030a565b8063cc4b26a314610668578063cd3b5dfb1461067b578063cfc14f53146106c55761030a565b8063ae4479dd11610181578063ae4479dd1461062f578063b42f60db14610642578063bfdeb719146106555761030a565b806391b46e051461059c578063ad037af6146105af5761030a565b806349d0e2ee1161026057806376668b67116102095780637a009135116101e35780637a009135146104fb5780637a1a04df1461050e57806383a042291461053c5761030a565b806376668b67146104ac57806376c308f2146104bf578063797384b2146104c85761030a565b80636d8d36ba1161023a5780636d8d36ba146104735780636e60e2491461048657806372d01257146104995761030a565b806349d0e2ee1461042d5780634b86daab1461044057806364f85ab1146104535761030a565b806328108026116102c2578063392f5f641161029c578063392f5f64146103e0578063447d52ba1461040757806346c87f801461041a5761030a565b806328108026146103795780632a6a897b146103ba57806336953912146103cd5761030a565b806314189db2116102f357806314189db21461033757806316de7a431461035d578063267031b8146103705761030a565b8063071060a61461030f5780630f7c43dc14610324575b600080fd5b61032261031d366004612a4c565b610820565b005b6103226103323660046129cd565b610917565b61034a610345366004612916565b6109a5565b6040519081526020015b60405180910390f35b61032261036b3660046129cd565b6109d0565b61034a60095481565b6103a2610387366004612916565b600a602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610354565b6103226103c83660046129cd565b610a62565b6103226103db366004612a4c565b610b01565b6103a27f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c81565b610322610415366004612a64565b610b7f565b61034a610428366004612916565b610c70565b61032261043b366004612a4c565b610c98565b61032261044e366004612916565b610d16565b61034a610461366004612916565b600b6020526000908152604090205481565b6103226104813660046129cd565b610d23565b61034a610494366004612955565b610e44565b61034a6104a7366004612916565b610ebe565b61034a6104ba366004612a88565b610edf565b61034a60025481565b6104eb6104d6366004612916565b600c6020526000908152604090205460ff1681565b6040519015158152602001610354565b610322610509366004612916565b610f19565b6104eb61051c3660046129cd565b600160209081526000928352604080842090915290825290205460ff1681565b61057c61054a366004612955565b600860209081526000928352604080842090915290825290208054600182015460028301546003909301549192909184565b604080519485526020850193909352918301526060820152608001610354565b6103226105aa366004612a4c565b610fff565b6105fa6105bd366004612916565b6004602081905260009182526040909120805460018201546002830154600384015494840154600585015460069095015493959294919390919087565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e001610354565b61032261063d3660046129cd565b61107d565b6103226106503660046129f8565b611172565b61034a610663366004612916565b611269565b610322610676366004612916565b611301565b6106aa610689366004612916565b60056020526000908152604090208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610354565b6103226106d3366004612916565b611480565b61034a60075481565b6103226106ef3660046129cd565b6114d0565b610322610702366004612a4c565b6115b4565b61032261071536600461298d565b6115db565b61034a610728366004612916565b611651565b61074061073b366004612a88565b611681565b60408051928352602083019190915201610354565b61034a60035481565b6103a261076c366004612a4c565b6000602081905290815260409020546001600160a01b031681565b610322610795366004612955565b61176f565b6103a27f000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b81565b6103226107cf3660046129cd565b611891565b61034a6107e2366004612916565b611a12565b6103226107f5366004612a4c565b611a33565b610322610808366004612916565b611ab1565b61032261081b3660046129cd565b611b3a565b6040517fb4ed0b6d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b03169063b4ed0b6d9060240160206040518083038186803b15801561089957600080fd5b505afa1580156108ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d19190612939565b60009182526020829052604090912080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055565b6001600160a01b03821660009081526008602090815260408083203380855292529091209061094b90849083908590611cfe565b805461098a576001600160a01b038316600090815260086020908152604080832033845290915281208181556001810182905560028101829055600301555b610995833384611de4565b6109a0833384611f6d565b505050565b6001600160a01b03811660009081526005602052604081206109c78142611fb9565b9150505b919050565b6001600160a01b0382166000908152600c602052604090205460ff16610a3d5760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f766564206973737565720000000000000000000000000060448201526064015b60405180910390fd5b610a48823383611ffa565b610a538233836120b9565b610a5e82338361212c565b5050565b3360009081526001602090815260408083206003845290915290205460ff16610acd5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b03821660009081526004602052604081206001018054839290610af8908490612b17565b90915550505050565b33610b0a61216f565b6001600160a01b03161480610b2e575033610b23612207565b6001600160a01b0316145b610b7a5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600755565b6040517f93552a3d000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382811660248301527f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c16906393552a3d9060440160206040518083038186803b158015610c0057600080fd5b505afa158015610c14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c389190612a2c565b6001600160a01b0391909116600090815260016020908152604080832094835293905291909120805460ff1916911515919091179055565b6001600160a01b0381166000908152600560205260408120610c9181612278565b5492915050565b33610ca161216f565b6001600160a01b03161480610cc5575033610cba612207565b6001600160a01b0316145b610d115760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600355565b610d20818261176f565b50565b336000908152600160209081526040808320600b845290915290205460ff16610d8e5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff16610df65760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e1881836122ac565b6001600160a01b0383166000908152600660205260409020610e3e9084906102586122c9565b50505050565b6001600160a01b038083166000818152600860209081526040808320948616835293815283822060018101549383526006909152928120909291908390610e8b9042611fb9565b90508115610eaa578254610ea09082846123e2565b9350505050610eb8565b5050549050610eb8565b5050505b92915050565b6001600160a01b0381166000908152600660205260408120610eb890612401565b6001600160a01b03821660009081526005602052604081208190610f039042611fb9565b9050610f108582856123e2565b95945050505050565b33610f2261216f565b6001600160a01b03161480610f46575033610f3b612207565b6001600160a01b0316145b80610f6c57503360009081526001602090815260408083206009845290915290205460ff165b610fde5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03166000908152600c60205260409020805460ff19169055565b3361100861216f565b6001600160a01b0316148061102c575033611021612207565b6001600160a01b0316145b6110785760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600955565b336000908152600160209081526040808320600b845290915290205460ff166110e85760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166111505760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600460205260409020610e188183612461565b3361117b61216f565b6001600160a01b0316148061119f575033611194612207565b6001600160a01b0316145b806111c557503360009081526001602090815260408083206009845290915290205460ff165b6112375760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b0390921660009081526004602081905260409091206005810193909355600683019190915542910155565b6001600160a01b0381166000908152600460205260408120600581015442118061129a575080600501548160040154115b156112a95760009150506109cb565b6000816004015482600501546112bf9190612b17565b82549091506112cf908290612ada565b6112da906001612aae565b60068301546112ee9064496cebb800612ada565b6112f89190612ac6565b925050506109cb565b3361130a61216f565b6001600160a01b0316148061132e575033611323612207565b6001600160a01b0316145b8061135457503360009081526001602090815260408083206009845290915290205460ff165b6113c65760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b038116600090815260056020526040902080541561142d5760405162461bcd60e51b815260206004820152601360248201527f646f6e27742072652d696e697469616c697a65000000000000000000000000006044820152606401610a34565b6601000000000000808255426001830155612238906103e89061145290601990612ada565b61145c9190612ac6565b6114669190612ac6565b611477906601000000000000612aae565b60029091015550565b6001600160a01b03811660009081526004602052604090206114a18161247e565b6001600160a01b0382166000908152600860209081526040808320338085529252909120610a5e918390612563565b336114d961216f565b6001600160a01b031614806114fd5750336114f2612207565b6001600160a01b0316145b8061152357503360009081526001602090815260408083206009845290915290205460ff165b6115955760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03909116600090815260046020526040902060020155565b336000908152600b6020526040812080548392906115d3908490612aae565b909155505050565b336000908152600160209081526040808320600b845290915290205460ff166116465760405162461bcd60e51b815260206004820152601660248201527f4e6f7420616e20617070726f766564206c656e646572000000000000000000006044820152606401610a34565b6109a08383836120b9565b6001600160a01b03811660009081526006602052604081206116779083906102586122c9565b6002015492915050565b33600090815260016020908152604080832060038452909152812054819060ff166116ee5760405162461bcd60e51b815260206004820152601160248201527f4e6f7420617070726f7665642063616c6c0000000000000000000000000000006044820152606401610a34565b6001600160a01b038416600090815260056020526040902061170f81612278565b8054915061171e8683866123e2565b9250600061172c8785612b17565b6001600160a01b0387166000908152600460205260408120600181018054939450909284929061175d908490612aae565b92505081905550505050935093915050565b3361177861216f565b6001600160a01b0316148061179c575033611791612207565b6001600160a01b0316145b806117c257503360009081526001602090815260408083206009845290915290205460ff165b6118345760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b039182166000908152600c60209081526040808320805460ff19166001179055600a90915290208054919092167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116179055565b3360009081526001602090815260408083206003845290915290205460ff166118fc5760405162461bcd60e51b815260206004820152601560248201527f4e6f7420617070726f76656420626f72726f77657200000000000000000000006044820152606401610a34565b6001600160a01b0382166000908152600c602052604090205460ff166119645760405162461bcd60e51b815260206004820152601360248201527f4e6f7420617070726f76656420697373756572000000000000000000000000006044820152606401610a34565b6001600160a01b038216600090815260046020526040812060018101805491928492611991908490612aae565b90915550506001600160a01b03831660009081526006602052604090206119bc908490610e106122c9565b506001810154815410156109a05760405162461bcd60e51b815260206004820152601460248201527f496e73756666696369656e74206c656e64696e670000000000000000000000006044820152606401610a34565b6001600160a01b0381166000908152600560205260408120610eb890612401565b33611a3c61216f565b6001600160a01b03161480611a60575033611a55612207565b6001600160a01b0316145b611aac5760405162461bcd60e51b815260206004820152601e60248201527f526f6c65733a2063616c6c6572206973206e6f7420746865206f776e657200006044820152606401610a34565b600255565b6001600160a01b038116600090815260086020908152604080832033808552925290912080549091611ae890849084908490611cfe565b611af3833383611de4565b6001600160a01b038316600090815260086020908152604080832033808552925282208281556001810183905560028101839055600301919091556109a090849083611f6d565b33611b4361216f565b6001600160a01b03161480611b67575033611b5c612207565b6001600160a01b0316145b80611b8d57503360009081526001602090815260408083206009845290915290205460ff165b611bff5760405162461bcd60e51b815260206004820152603960248201527f43616c6c6572206973206e6f7420746865206f776e65722c206578656375746f60448201527f72206f7220617574686f72697a656420616374697661746f72000000000000006064820152608401610a34565b6001600160a01b03821660009081526006602052604090208054611cae5760006122386064611c35856601000000000000612ada565b611c3f9190612ac6565b611c499190612ac6565b611c5a906601000000000000612aae565b60408051606081018252660100000000000081524260208083019182528284019485526001600160a01b038916600090815260069091529290922090518155905160018201559051600290910155506109a0565b6000611cbd84836102586122c9565b90506122386064611cce8582612aae565b611cdf906601000000000000612ada565b611ce99190612ac6565b611cf39190612ac6565b600290910155505050565b6001600160a01b0384166000908152600460205260409020611d2090836122ac565b611d2b848483612699565b6000610e10846002015442611d409190612b17565b611d4a9190612b67565b9050806007541015611dc45760405162461bcd60e51b815260206004820152603f60248201527f5472696564207769746864726177696e67206f7574736964652073756273637260448201527f697074696f6e2063616e63656c6c6174696f6e2074696d652077696e646f77006064820152608401610a34565b82846000016000828254611dd89190612b17565b90915550505050505050565b6001600160a01b0383166000908152600b60205260409020548015801590611e0c5750600082115b15611e8b576001600160a01b0384166000908152600460205260408120549081611e36818561273f565b611e409086612ada565b611e4a9190612ac6565b9050611e568185612b17565b6001600160a01b0387166000908152600b6020526040812080549296508392909190611e83908490612b17565b909155505050505b6001600160a01b038085166000908152600a602052604090205416611ee1606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152868116602483015260448201869052919091169063d9caed1290606401600060405180830381600087803b158015611f4e57600080fd5b505af1158015611f62573d6000803e3d6000fd5b505050505050505050565b604080516001600160a01b038581168252602082018490528416917f3397b60e3ca1e9c0c75a033d62ab8731e9b2937c0690ae5d7f1bd37886b19d7d91015b60405180910390a2505050565b600080836001015483611fcc9190612b17565b9050610258811115611fea57611fe28482612757565b915050610eb8565b50508154610eb8565b5092915050565b7f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b038481166000908152600a60205260408082205481517fb3db428b00000000000000000000000000000000000000000000000000000000815287851660048201529084166024820152604481018690529051929093169263b3db428b926064808301939282900301818387803b15801561209c57600080fd5b505af11580156120b0573d6000803e3d6000fd5b50505050505050565b6001600160a01b038084166000818152600860209081526040808320948716835293815283822092825260049052919091206120f58184612461565b612100858386612699565b815461211857612112610e1042612b67565b60028301555b82826000016000828254611dd89190612aae565b604080516001600160a01b038581168252602082018490528416917f8ec70c9430377a4bba035133e27a5b0f3b9951bc080833f6832bcbbb70a96dba9101611fac565b60007f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ca57600080fd5b505afa1580156121de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122029190612939565b905090565b60007f000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c6001600160a01b031663c34c08e56040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561226457600080fd5b505af11580156121de573d6000803e3d6000fd5b600081600101544261228a9190612b17565b9050610258811115610a5e576122a08282612757565b82554260018301555050565b6122b58261247e565b80826000016000828254610af89190612b17565b6001820154600090816122dc8242612b17565b9050838111156123d8576001600160a01b03861660009081526005602052604090206123088683612757565b86556001600160a01b038716600090815260046020526040902080546001820154612333919061286f565b600288015542600188015561234782612278565b6123cd6122386103e861236266010000000000006019612ada565b61236c9190612ac6565b6123769190612ac6565b612387906601000000000000612aae565b606466010000000000008a600201546123a09190612b17565b6009546123ad9190612ada565b6123b79190612ac6565b6123c8906601000000000000612aae565b6128fe565b826002018190555050505b5092949350505050565b6000816123ef8486612ada565b6123f99190612ac6565b949350505050565b600281015460009081610e106124206601000000000000612710612ada565b61242c84612710612ada565b6124369190612b17565b612444906301e13380612ada565b61244e9190612ac6565b90506123f9660100000000000082612ac6565b61246a8261247e565b80826000016000828254610af89190612aae565b600061248e82600501544261273f565b9050600082600601541180156124a75750816004015481115b15610a5e5760008260040154826124be9190612b17565b905060006124fc8460060154856004015486600501546124de9190612b17565b60068701546124ed9086612ada565b6124f79190612ac6565b61273f565b9050808460060160008282546125129190612b17565b90915550508354612524906001612aae565b612535660100000000000083612ada565b61253f9190612ac6565b8460030160008282546125529190612aae565b909155505042600485015550505050565b6000836003015483600301546125799190612b17565b90508015610e3e5783546000906601000000000000906125999084612ada565b6125a39190612ac6565b90506125e0606560009081526020527f4a7203f705e51df4a56139a9b86b4a0970bed7ab7a3446eaffe2289989c1645c546001600160a01b031690565b6040517fd9caed120000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b81166004830152858116602483015260448201849052919091169063d9caed1290606401600060405180830381600087803b15801561266d57600080fd5b505af1158015612681573d6000803e3d6000fd5b5050505081856003016000828254611dd89190612aae565b60018201546001600160a01b03841660009081526006602052604081206126c49086906102586122c9565b6001600160a01b03861660009081526004602052604090209091508215612724576126f0858286612563565b84548254612700908290866123e2565b808755600090612711908390612b17565b905061271d8382612461565b505061272f565b600380820154908601555b5054600190930192909255505050565b600081831115612750575080610eb8565b5081610eb8565b600080612766610e1084612b67565b905061277b6601000000000000610e10612ada565b81660100000000000086600201546127939190612b17565b865461279f9190612ada565b6127a99190612ada565b6127b39190612ac6565b84546127bf9190612aae565b915060006127cf610e1085612ac6565b90508015612867578260005b80831180156127ea5750806004115b156128255766010000000000008760020154866128079190612ada565b6128119190612ac6565b94508061281d81612b2e565b9150506127db565b506004821115610eb457600461283b8184612b17565b6128458387612b17565b61284f9190612ada565b6128599190612ac6565b6128639085612aae565b9350505b505092915050565b660100000000000060008361288557600061289b565b83612891846064612ada565b61289b9190612ac6565b905060528110156128c4576002546128b39082612ada565b6128bd9083612aae565b9150611ff3565b6003546128d2605283612b17565b6128dc9190612ada565b6002546128ea906052612ada565b6128f49190612aae565b6123f99083612aae565b60008183111561290f575081610eb8565b5080610eb8565b600060208284031215612927578081fd5b813561293281612bd9565b9392505050565b60006020828403121561294a578081fd5b815161293281612bd9565b60008060408385031215612967578081fd5b823561297281612bd9565b9150602083013561298281612bd9565b809150509250929050565b6000806000606084860312156129a1578081fd5b83356129ac81612bd9565b925060208401356129bc81612bd9565b929592945050506040919091013590565b600080604083850312156129df578182fd5b82356129ea81612bd9565b946020939093013593505050565b600080600060608486031215612a0c578283fd5b8335612a1781612bd9565b95602085013595506040909401359392505050565b600060208284031215612a3d578081fd5b81518015158114612932578182fd5b600060208284031215612a5d578081fd5b5035919050565b60008060408385031215612a76578182fd5b82359150602083013561298281612bd9565b600080600060608486031215612a9c578283fd5b8335925060208401356129bc81612bd9565b60008219821115612ac157612ac1612b7b565b500190565b600082612ad557612ad5612baa565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612b1257612b12612b7b565b500290565b600082821015612b2957612b29612b7b565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612b6057612b60612b7b565b5060010190565b600082612b7657612b76612baa565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6001600160a01b0381168114610d2057600080fdfea26469706673582212208a451470ba8ee8ff877e735ffaac79f28bd8ba5c62f6730bd169f0963e1d946e64736f6c63430008030033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
-----Decoded View---------------
Arg [0] : _MFI (address): 0xAa4e3edb11AFa93c41db59842b29de64b72E355B
Arg [1] : _roles (address): 0xC6D13A49cdC5Afc7798dd0eBA7698DB9BFCc1D8c
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000aa4e3edb11afa93c41db59842b29de64b72e355b
Arg [1] : 000000000000000000000000c6d13a49cdc5afc7798dd0eba7698db9bfcc1d8c
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.