Source Code
Overview
S Balance
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Cover
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.18; import "@openzeppelin/contracts-v4/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts-v4/token/ERC20/utils/SafeERC20.sol"; import "../../abstract/MasterAwareV2.sol"; import "../../abstract/Multicall.sol"; import "../../interfaces/ICover.sol"; import "../../interfaces/ICoverNFT.sol"; import "../../interfaces/ICoverProducts.sol"; import "../../interfaces/IPool.sol"; import "../../interfaces/IStakingNFT.sol"; import "../../interfaces/IStakingPool.sol"; import "../../interfaces/IStakingPoolBeacon.sol"; import "../../interfaces/ICompleteStakingPoolFactory.sol"; import "../../interfaces/ITokenController.sol"; import "../../libraries/Math.sol"; import "../../libraries/SafeUintCast.sol"; import "../../libraries/StakingPoolLibrary.sol"; contract Cover is ICover, MasterAwareV2, IStakingPoolBeacon, ReentrancyGuard, Multicall { using SafeERC20 for IERC20; using SafeUintCast for uint; /* ========== STATE VARIABLES ========== */ // moved to cover products Product[] private _unused_products; ProductType[] private _unused_productTypes; mapping(uint => CoverData) private _coverData; // cover id => segment id => pool allocations array mapping(uint => mapping(uint => PoolAllocation[])) public coverSegmentAllocations; // moved to cover products mapping(uint => uint[]) private _unused_allowedPools; // Each cover has an array of segments. A new segment is created // every time a cover is edited to indicate the different cover periods. mapping(uint => CoverSegment[]) private _coverSegments; // assetId => { lastBucketUpdateId, totalActiveCoverInAsset } mapping(uint => ActiveCover) public activeCover; // assetId => bucketId => amount mapping(uint => mapping(uint => uint)) internal activeCoverExpirationBuckets; // moved to cover products mapping(uint => string) private _unused_productNames; mapping(uint => string) private _unused_productTypeNames; /* ========== CONSTANTS ========== */ uint private constant GLOBAL_CAPACITY_RATIO = 20000; // 2 uint private constant GLOBAL_REWARDS_RATIO = 5000; // 50% uint private constant COMMISSION_DENOMINATOR = 10000; uint private constant GLOBAL_CAPACITY_DENOMINATOR = 10_000; uint private constant MAX_COVER_PERIOD = 365 days; uint private constant MIN_COVER_PERIOD = 28 days; uint private constant BUCKET_SIZE = 7 days; uint public constant MAX_COMMISSION_RATIO = 3000; // 30% uint public constant GLOBAL_MIN_PRICE_RATIO = 100; // 1% uint private constant ONE_NXM = 1e18; uint private constant ETH_ASSET_ID = 0; uint private constant NXM_ASSET_ID = type(uint8).max; // internally we store capacity using 2 decimals // 1 nxm of capacity is stored as 100 uint private constant ALLOCATION_UNITS_PER_NXM = 100; // given capacities have 2 decimals // smallest unit we can allocate is 1e18 / 100 = 1e16 = 0.01 NXM uint public constant NXM_PER_ALLOCATION_UNIT = ONE_NXM / ALLOCATION_UNITS_PER_NXM; ICoverNFT public immutable override coverNFT; IStakingNFT public immutable override stakingNFT; ICompleteStakingPoolFactory public immutable override stakingPoolFactory; address public immutable stakingPoolImplementation; /* ========== CONSTRUCTOR ========== */ constructor( ICoverNFT _coverNFT, IStakingNFT _stakingNFT, ICompleteStakingPoolFactory _stakingPoolFactory, address _stakingPoolImplementation ) { // in constructor we only initialize immutable fields coverNFT = _coverNFT; stakingNFT = _stakingNFT; stakingPoolFactory = _stakingPoolFactory; stakingPoolImplementation = _stakingPoolImplementation; } /* === MUTATIVE FUNCTIONS ==== */ function buyCover( BuyCoverParams memory params, PoolAllocationRequest[] memory poolAllocationRequests ) external payable onlyMember nonReentrant whenNotPaused returns (uint coverId) { if (params.period < MIN_COVER_PERIOD) { revert CoverPeriodTooShort(); } if (params.period > MAX_COVER_PERIOD) { revert CoverPeriodTooLong(); } if (params.commissionRatio > MAX_COMMISSION_RATIO) { revert CommissionRateTooHigh(); } if (params.amount == 0) { revert CoverAmountIsZero(); } // can pay with cover asset or nxm only if (params.paymentAsset != params.coverAsset && params.paymentAsset != NXM_ASSET_ID) { revert InvalidPaymentAsset(); } uint segmentId; AllocationRequest memory allocationRequest; { ICoverProducts _coverProducts = coverProducts(); if (_coverProducts.getProductCount() <= params.productId) { revert ProductNotFound(); } ( Product memory product, ProductType memory productType ) = _coverProducts.getProductWithType(params.productId); if (product.isDeprecated) { revert ProductDeprecated(); } if (!isCoverAssetSupported(params.coverAsset, product.coverAssets)) { revert CoverAssetNotSupported(); } allocationRequest.productId = params.productId; allocationRequest.coverId = coverId; allocationRequest.period = params.period; allocationRequest.gracePeriod = productType.gracePeriod; allocationRequest.useFixedPrice = product.useFixedPrice; allocationRequest.globalCapacityRatio = GLOBAL_CAPACITY_RATIO; allocationRequest.capacityReductionRatio = product.capacityReductionRatio; allocationRequest.rewardRatio = GLOBAL_REWARDS_RATIO; allocationRequest.globalMinPrice = GLOBAL_MIN_PRICE_RATIO; } uint previousSegmentAmount; if (params.coverId == 0) { // new cover coverId = coverNFT.mint(params.owner); _coverData[coverId] = CoverData(params.productId, params.coverAsset, 0 /* amountPaidOut */); } else { revert EditNotSupported(); /* // existing cover coverId = params.coverId; if (!coverNFT.isApprovedOrOwner(msg.sender, coverId)) { revert OnlyOwnerOrApproved(); } CoverData memory cover = _coverData[coverId]; if (params.coverAsset != cover.coverAsset) { revert UnexpectedCoverAsset(); } if (params.productId != cover.productId) { revert UnexpectedProductId(); } segmentId = _coverSegments[coverId].length; CoverSegment memory lastSegment = coverSegmentWithRemainingAmount(coverId, segmentId - 1); // require last segment not to be expired if (lastSegment.start + lastSegment.period <= block.timestamp) { revert ExpiredCoversCannotBeEdited(); } allocationRequest.previousStart = lastSegment.start; allocationRequest.previousExpiration = lastSegment.start + lastSegment.period; allocationRequest.previousRewardsRatio = lastSegment.globalRewardsRatio; // mark previous cover as ending now _coverSegments[coverId][segmentId - 1].period = (block.timestamp - lastSegment.start).toUint32(); // remove cover amount from from expiration buckets uint bucketAtExpiry = Math.divCeil(lastSegment.start + lastSegment.period, BUCKET_SIZE); activeCoverExpirationBuckets[params.coverAsset][bucketAtExpiry] -= lastSegment.amount; previousSegmentAmount += lastSegment.amount; */ } uint nxmPriceInCoverAsset = pool().getInternalTokenPriceInAssetAndUpdateTwap(params.coverAsset); allocationRequest.coverId = coverId; (uint coverAmountInCoverAsset, uint amountDueInNXM) = requestAllocation( allocationRequest, poolAllocationRequests, nxmPriceInCoverAsset, segmentId ); if (coverAmountInCoverAsset < params.amount) { revert InsufficientCoverAmountAllocated(); } _coverSegments[coverId].push( CoverSegment( coverAmountInCoverAsset.toUint96(), // cover amount in cover asset block.timestamp.toUint32(), // start params.period, // period allocationRequest.gracePeriod.toUint32(), GLOBAL_REWARDS_RATIO.toUint24(), GLOBAL_CAPACITY_RATIO.toUint24() ) ); _updateTotalActiveCoverAmount(params.coverAsset, coverAmountInCoverAsset, params.period, previousSegmentAmount); retrievePayment( amountDueInNXM, params.paymentAsset, nxmPriceInCoverAsset, params.maxPremiumInAsset, params.commissionRatio, params.commissionDestination ); emit CoverEdited(coverId, params.productId, segmentId, msg.sender, params.ipfsData); } function expireCover(uint coverId) external { uint segmentId = _coverSegments[coverId].length - 1; CoverSegment memory lastSegment = coverSegmentWithRemainingAmount(coverId, segmentId); CoverData memory cover = _coverData[coverId]; uint expiration = lastSegment.start + lastSegment.period; if (expiration > block.timestamp) { revert CoverNotYetExpired(coverId); } for ( uint allocationIndex = 0; allocationIndex < coverSegmentAllocations[coverId][segmentId].length; allocationIndex++ ) { PoolAllocation memory allocation = coverSegmentAllocations[coverId][segmentId][allocationIndex]; AllocationRequest memory allocationRequest; // editing just the needed props for deallocation allocationRequest.productId = cover.productId; allocationRequest.allocationId = allocation.allocationId; allocationRequest.previousStart = lastSegment.start; allocationRequest.previousExpiration = expiration; stakingPool(allocation.poolId).requestAllocation( 0, // amount 0, // previous premium allocationRequest ); } uint currentBucketId = block.timestamp / BUCKET_SIZE; uint bucketAtExpiry = Math.divCeil(expiration, BUCKET_SIZE); // if it expires in a future bucket if (currentBucketId < bucketAtExpiry) { // remove cover amount from expiration buckets and totalActiveCoverInAsset without updating last bucket id activeCoverExpirationBuckets[cover.coverAsset][bucketAtExpiry] -= lastSegment.amount; activeCover[cover.coverAsset].totalActiveCoverInAsset -= lastSegment.amount; } } function requestAllocation( AllocationRequest memory allocationRequest, PoolAllocationRequest[] memory poolAllocationRequests, uint nxmPriceInCoverAsset, uint segmentId ) internal returns ( uint totalCoverAmountInCoverAsset, uint totalAmountDueInNXM ) { RequestAllocationVariables memory vars = RequestAllocationVariables(0, 0, 0, 0); uint totalCoverAmountInNXM; vars.previousPoolAllocationsLength = segmentId > 0 ? coverSegmentAllocations[allocationRequest.coverId][segmentId - 1].length : 0; for (uint i = 0; i < poolAllocationRequests.length; i++) { // if there is a previous segment and this index is present on it if (vars.previousPoolAllocationsLength > i) { PoolAllocation memory previousPoolAllocation = coverSegmentAllocations[allocationRequest.coverId][segmentId - 1][i]; // poolAllocationRequests must match the pools in the previous segment if (previousPoolAllocation.poolId != poolAllocationRequests[i].poolId) { revert UnexpectedPoolId(); } // check if this request should be skipped, keeping the previous allocation if (poolAllocationRequests[i].skip) { coverSegmentAllocations[allocationRequest.coverId][segmentId].push(previousPoolAllocation); totalCoverAmountInNXM += previousPoolAllocation.coverAmountInNXM; continue; } vars.previousPremiumInNXM = previousPoolAllocation.premiumInNXM; vars.refund = previousPoolAllocation.premiumInNXM * (allocationRequest.previousExpiration - block.timestamp) // remaining period / (allocationRequest.previousExpiration - allocationRequest.previousStart); // previous period // get stored allocation id allocationRequest.allocationId = previousPoolAllocation.allocationId; } else { // request new allocation id allocationRequest.allocationId = 0; } // converting asset amount to nxm and rounding up to the nearest NXM_PER_ALLOCATION_UNIT uint coverAmountInNXM = Math.roundUp( Math.divCeil(poolAllocationRequests[i].coverAmountInAsset * ONE_NXM, nxmPriceInCoverAsset), NXM_PER_ALLOCATION_UNIT ); (uint premiumInNXM, uint allocationId) = stakingPool(poolAllocationRequests[i].poolId).requestAllocation( coverAmountInNXM, vars.previousPremiumInNXM, allocationRequest ); // omit deallocated pools from the segment if (coverAmountInNXM != 0) { coverSegmentAllocations[allocationRequest.coverId][segmentId].push( PoolAllocation( poolAllocationRequests[i].poolId, coverAmountInNXM.toUint96(), premiumInNXM.toUint96(), allocationId.toUint24() ) ); } totalAmountDueInNXM += (vars.refund >= premiumInNXM ? 0 : premiumInNXM - vars.refund); totalCoverAmountInNXM += coverAmountInNXM; } totalCoverAmountInCoverAsset = totalCoverAmountInNXM * nxmPriceInCoverAsset / ONE_NXM; return (totalCoverAmountInCoverAsset, totalAmountDueInNXM); } function retrievePayment( uint premiumInNxm, uint paymentAsset, uint nxmPriceInCoverAsset, uint maxPremiumInAsset, uint16 commissionRatio, address commissionDestination ) internal { if (paymentAsset != ETH_ASSET_ID && msg.value > 0) { revert UnexpectedEthSent(); } // NXM payment if (paymentAsset == NXM_ASSET_ID) { uint commissionInNxm; if (commissionRatio > 0) { commissionInNxm = (premiumInNxm * COMMISSION_DENOMINATOR / (COMMISSION_DENOMINATOR - commissionRatio)) - premiumInNxm; } if (premiumInNxm + commissionInNxm > maxPremiumInAsset) { revert PriceExceedsMaxPremiumInAsset(); } ITokenController _tokenController = tokenController(); _tokenController.burnFrom(msg.sender, premiumInNxm); if (commissionInNxm > 0) { // commission transfer reverts if the commissionDestination is not a member _tokenController.operatorTransfer(msg.sender, commissionDestination, commissionInNxm); } return; } IPool _pool = pool(); uint premiumInPaymentAsset = nxmPriceInCoverAsset * premiumInNxm / ONE_NXM; uint commission = (premiumInPaymentAsset * COMMISSION_DENOMINATOR / (COMMISSION_DENOMINATOR - commissionRatio)) - premiumInPaymentAsset; uint premiumWithCommission = premiumInPaymentAsset + commission; if (premiumWithCommission > maxPremiumInAsset) { revert PriceExceedsMaxPremiumInAsset(); } // ETH payment if (paymentAsset == ETH_ASSET_ID) { if (msg.value < premiumWithCommission) { revert InsufficientEthSent(); } uint remainder = msg.value - premiumWithCommission; { // send premium in eth to the pool // solhint-disable-next-line avoid-low-level-calls (bool ok, /* data */) = address(_pool).call{value: premiumInPaymentAsset}(""); if (!ok) { revert SendingEthToPoolFailed(); } } // send commission if (commission > 0) { (bool ok, /* data */) = address(commissionDestination).call{value: commission}(""); if (!ok) { revert SendingEthToCommissionDestinationFailed(); } } if (remainder > 0) { // solhint-disable-next-line avoid-low-level-calls (bool ok, /* data */) = address(msg.sender).call{value: remainder}(""); if (!ok) { revert ReturningEthRemainderToSenderFailed(); } } return; } address coverAsset = _pool.getAsset(paymentAsset).assetAddress; IERC20 token = IERC20(coverAsset); token.safeTransferFrom(msg.sender, address(_pool), premiumInPaymentAsset); if (commission > 0) { token.safeTransferFrom(msg.sender, commissionDestination, commission); } } function updateTotalActiveCoverAmount(uint coverAsset) public { _updateTotalActiveCoverAmount(coverAsset, 0, 0, 0); } function _updateTotalActiveCoverAmount( uint coverAsset, uint newCoverAmountInAsset, uint coverPeriod, uint previousCoverSegmentAmount ) internal { ActiveCover memory _activeCover = activeCover[coverAsset]; uint currentBucketId = block.timestamp / BUCKET_SIZE; uint totalActiveCover = _activeCover.totalActiveCoverInAsset; if (totalActiveCover != 0) { totalActiveCover -= getExpiredCoverAmount( coverAsset, _activeCover.lastBucketUpdateId, currentBucketId ); } totalActiveCover -= previousCoverSegmentAmount; totalActiveCover += newCoverAmountInAsset; _activeCover.lastBucketUpdateId = currentBucketId.toUint64(); _activeCover.totalActiveCoverInAsset = totalActiveCover.toUint192(); // update total active cover in storage activeCover[coverAsset] = _activeCover; // update amount to expire at the end of this cover segment uint bucketAtExpiry = Math.divCeil(block.timestamp + coverPeriod, BUCKET_SIZE); activeCoverExpirationBuckets[coverAsset][bucketAtExpiry] += newCoverAmountInAsset; } // Gets the total amount of active cover that is currently expired for this asset function getExpiredCoverAmount( uint coverAsset, uint lastUpdateId, uint currentBucketId ) internal view returns (uint amountExpired) { while (lastUpdateId < currentBucketId) { ++lastUpdateId; amountExpired += activeCoverExpirationBuckets[coverAsset][lastUpdateId]; } return amountExpired; } function burnStake( uint coverId, uint segmentId, uint payoutAmountInAsset ) external onlyInternal override returns (address /* coverOwner */) { CoverData storage cover = _coverData[coverId]; ActiveCover storage _activeCover = activeCover[cover.coverAsset]; CoverSegment memory segment = coverSegmentWithRemainingAmount(coverId, segmentId); PoolAllocation[] storage allocations = coverSegmentAllocations[coverId][segmentId]; // update expired buckets and calculate the amount of active cover that should be burned { uint coverAsset = cover.coverAsset; uint lastUpdateBucketId = _activeCover.lastBucketUpdateId; uint currentBucketId = block.timestamp / BUCKET_SIZE; uint burnedSegmentBucketId = Math.divCeil((segment.start + segment.period), BUCKET_SIZE); uint activeCoverToExpire = getExpiredCoverAmount(coverAsset, lastUpdateBucketId, currentBucketId); // if the segment has not expired - it's still accounted for in total active cover if (burnedSegmentBucketId > currentBucketId) { uint amountToSubtract = Math.min(payoutAmountInAsset, segment.amount); activeCoverToExpire += amountToSubtract; activeCoverExpirationBuckets[coverAsset][burnedSegmentBucketId] -= amountToSubtract.toUint192(); } _activeCover.totalActiveCoverInAsset -= activeCoverToExpire.toUint192(); _activeCover.lastBucketUpdateId = currentBucketId.toUint64(); } // increase amountPaidOut only *after* you read the segment cover.amountPaidOut += payoutAmountInAsset.toUint96(); for (uint i = 0; i < allocations.length; i++) { PoolAllocation memory allocation = allocations[i]; uint deallocationAmountInNXM = allocation.coverAmountInNXM * payoutAmountInAsset / segment.amount; uint burnAmountInNxm = deallocationAmountInNXM * GLOBAL_CAPACITY_DENOMINATOR / segment.globalCapacityRatio; allocations[i].coverAmountInNXM -= deallocationAmountInNXM.toUint96(); allocations[i].premiumInNXM -= (allocation.premiumInNXM * payoutAmountInAsset / segment.amount).toUint96(); BurnStakeParams memory params = BurnStakeParams( allocation.allocationId, cover.productId, segment.start, segment.period, deallocationAmountInNXM ); uint poolId = allocations[i].poolId; stakingPool(poolId).burnStake(burnAmountInNxm, params); } return coverNFT.ownerOf(coverId); } /* ========== VIEWS ========== */ function coverData(uint coverId) external override view returns (CoverData memory) { return _coverData[coverId]; } function coverSegmentWithRemainingAmount( uint coverId, uint segmentId ) public override view returns (CoverSegment memory) { CoverSegment memory segment = _coverSegments[coverId][segmentId]; uint96 amountPaidOut = _coverData[coverId].amountPaidOut; segment.amount = segment.amount >= amountPaidOut ? segment.amount - amountPaidOut : 0; return segment; } function coverSegments(uint coverId) external override view returns (CoverSegment[] memory) { return _coverSegments[coverId]; } function coverSegmentsCount(uint coverId) external override view returns (uint) { return _coverSegments[coverId].length; } function coverDataCount() external override view returns (uint) { return coverNFT.totalSupply(); } /* ========== COVER ASSETS HELPERS ========== */ function recalculateActiveCoverInAsset(uint coverAsset) public { uint currentBucketId = block.timestamp / BUCKET_SIZE; uint totalActiveCover = 0; uint yearlyBucketsCount = Math.divCeil(MAX_COVER_PERIOD, BUCKET_SIZE); for (uint i = 1; i <= yearlyBucketsCount; i++) { uint bucketId = currentBucketId + i; totalActiveCover += activeCoverExpirationBuckets[coverAsset][bucketId]; } activeCover[coverAsset] = ActiveCover(totalActiveCover.toUint192(), currentBucketId.toUint64()); } function totalActiveCoverInAsset(uint assetId) public view returns (uint) { return uint(activeCover[assetId].totalActiveCoverInAsset); } function getGlobalCapacityRatio() external pure returns (uint) { return GLOBAL_CAPACITY_RATIO; } function getGlobalRewardsRatio() external pure returns (uint) { return GLOBAL_REWARDS_RATIO; } function getGlobalMinPriceRatio() external pure returns (uint) { return GLOBAL_MIN_PRICE_RATIO; } function getGlobalCapacityAndPriceRatios() external pure returns ( uint _globalCapacityRatio, uint _globalMinPriceRatio ) { _globalCapacityRatio = GLOBAL_CAPACITY_RATIO; _globalMinPriceRatio = GLOBAL_MIN_PRICE_RATIO; } function isCoverAssetSupported(uint assetId, uint productCoverAssetsBitmap) internal view returns (bool) { if ( // product does not use default cover assets productCoverAssetsBitmap != 0 && // asset id is not in the product's cover assets bitmap ((1 << assetId) & productCoverAssetsBitmap == 0) ) { return false; } Asset memory asset = pool().getAsset(assetId); return asset.isCoverAsset && !asset.isAbandoned; } function stakingPool(uint poolId) public view returns (IStakingPool) { return IStakingPool( StakingPoolLibrary.getAddress(address(stakingPoolFactory), poolId) ); } function changeCoverNFTDescriptor(address _coverNFTDescriptor) external onlyAdvisoryBoard { coverNFT.changeNFTDescriptor(_coverNFTDescriptor); } function changeStakingNFTDescriptor(address _stakingNFTDescriptor) external onlyAdvisoryBoard { stakingNFT.changeNFTDescriptor(_stakingNFTDescriptor); } function changeStakingPoolFactoryOperator() external { address _operator = master.getLatestAddress("SP"); stakingPoolFactory.changeOperator(_operator); } /* ========== DEPENDENCIES ========== */ function pool() internal view returns (IPool) { return IPool(internalContracts[uint(ID.P1)]); } function tokenController() internal view returns (ITokenController) { return ITokenController(internalContracts[uint(ID.TC)]); } function memberRoles() internal view returns (IMemberRoles) { return IMemberRoles(internalContracts[uint(ID.MR)]); } function coverProducts() internal view returns (ICoverProducts) { return ICoverProducts(internalContracts[uint(ID.CP)]); } function changeDependentContractAddress() external override { internalContracts[uint(ID.P1)] = master.getLatestAddress("P1"); internalContracts[uint(ID.TC)] = master.getLatestAddress("TC"); internalContracts[uint(ID.MR)] = master.getLatestAddress("MR"); internalContracts[uint(ID.CP)] = master.getLatestAddress("CP"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.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' 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)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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"); (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"); (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"); (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"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.18; import "../interfaces/ISAFURAMaster.sol"; import "../interfaces/IMasterAwareV2.sol"; import "../interfaces/IMemberRoles.sol"; abstract contract MasterAwareV2 is IMasterAwareV2 { ISAFURAMaster public master; mapping(uint => address payable) public internalContracts; modifier onlyMember { require( IMemberRoles(internalContracts[uint(ID.MR)]).checkRole( msg.sender, uint(IMemberRoles.Role.Member) ), "Caller is not a member" ); _; } modifier onlyAdvisoryBoard { require( IMemberRoles(internalContracts[uint(ID.MR)]).checkRole( msg.sender, uint(IMemberRoles.Role.AdvisoryBoard) ), "Caller is not an advisory board member" ); _; } modifier onlyInternal { require(master.isInternal(msg.sender), "Caller is not an internal contract"); _; } modifier onlyMaster { if (address(master) != address(0)) { require(address(master) == msg.sender, "Not master"); } _; } modifier onlyGovernance { require( master.checkIsAuthToGoverned(msg.sender), "Caller is not authorized to govern" ); _; } modifier onlyEmergencyAdmin { require( msg.sender == master.emergencyAdmin(), "Caller is not emergency admin" ); _; } modifier whenPaused { require(master.isPause(), "System is not paused"); _; } modifier whenNotPaused { require(!master.isPause(), "System is paused"); _; } function getInternalContractAddress(ID id) internal view returns (address payable) { return internalContracts[uint(id)]; } function changeMasterAddress(address masterAddress) public onlyMaster { master = ISAFURAMaster(masterAddress); } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.18; abstract contract Multicall { error RevertedWithoutReason(uint index); // WARNING: Do not set this function as payable function multicall(bytes[] calldata data) external returns (bytes[] memory results) { uint callCount = data.length; results = new bytes[](callCount); for (uint i = 0; i < callCount; i++) { (bool ok, bytes memory result) = address(this).delegatecall(data[i]); if (!ok) { uint length = result.length; // 0 length returned from empty revert() / require(false) if (length == 0) { revert RevertedWithoutReason(i); } assembly { revert(add(result, 0x20), length) } } results[i] = result; } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./IStakingPoolFactory.sol"; /** * @dev IStakingPoolFactory is missing the changeOperator() and operator() functions. * @dev Any change to the original interface will affect staking pool addresses * @dev This interface is created to add the missing functions so it can be used in other contracts. */ interface ICompleteStakingPoolFactory is IStakingPoolFactory { function operator() external view returns (address); function changeOperator(address newOperator) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./ICoverNFT.sol"; import "./IStakingNFT.sol"; import "./IStakingPool.sol"; import "./ICompleteStakingPoolFactory.sol"; /* io structs */ enum ClaimMethod { IndividualClaims, YieldTokenIncidents } struct PoolAllocationRequest { uint40 poolId; bool skip; uint coverAmountInAsset; } struct BuyCoverParams { uint coverId; address owner; uint24 productId; uint8 coverAsset; uint96 amount; uint32 period; uint maxPremiumInAsset; uint8 paymentAsset; uint16 commissionRatio; address commissionDestination; string ipfsData; } /* storage structs */ struct PoolAllocation { uint40 poolId; uint96 coverAmountInNXM; uint96 premiumInNXM; uint24 allocationId; } struct CoverData { uint24 productId; uint8 coverAsset; uint96 amountPaidOut; } struct CoverSegment { uint96 amount; uint32 start; uint32 period; // seconds uint32 gracePeriod; // seconds uint24 globalRewardsRatio; uint24 globalCapacityRatio; } interface ICover { /* ========== DATA STRUCTURES ========== */ /* internal structs */ struct RequestAllocationVariables { uint previousPoolAllocationsLength; uint previousPremiumInNXM; uint refund; uint coverAmountInNXM; } /* storage structs */ struct ActiveCover { // Global active cover amount per asset. uint192 totalActiveCoverInAsset; // The last time activeCoverExpirationBuckets was updated uint64 lastBucketUpdateId; } /* ========== VIEWS ========== */ function coverData(uint coverId) external view returns (CoverData memory); function coverDataCount() external view returns (uint); function coverSegmentsCount(uint coverId) external view returns (uint); function coverSegments(uint coverId) external view returns (CoverSegment[] memory); function coverSegmentWithRemainingAmount( uint coverId, uint segmentId ) external view returns (CoverSegment memory); function recalculateActiveCoverInAsset(uint coverAsset) external; function totalActiveCoverInAsset(uint coverAsset) external view returns (uint); function getGlobalCapacityRatio() external view returns (uint); function getGlobalRewardsRatio() external view returns (uint); function getGlobalMinPriceRatio() external pure returns (uint); function getGlobalCapacityAndPriceRatios() external view returns ( uint _globalCapacityRatio, uint _globalMinPriceRatio ); function GLOBAL_MIN_PRICE_RATIO() external view returns (uint); /* === MUTATIVE FUNCTIONS ==== */ function buyCover( BuyCoverParams calldata params, PoolAllocationRequest[] calldata coverChunkRequests ) external payable returns (uint coverId); function burnStake( uint coverId, uint segmentId, uint amount ) external returns (address coverOwner); function changeStakingPoolFactoryOperator() external; function coverNFT() external returns (ICoverNFT); function stakingNFT() external returns (IStakingNFT); function stakingPoolFactory() external returns (ICompleteStakingPoolFactory); /* ========== EVENTS ========== */ event CoverEdited(uint indexed coverId, uint indexed productId, uint indexed segmentId, address buyer, string ipfsMetadata); // Auth error OnlyOwnerOrApproved(); // Cover details error CoverPeriodTooShort(); error CoverPeriodTooLong(); error CoverOutsideOfTheGracePeriod(); error CoverAmountIsZero(); // Products error ProductNotFound(); error ProductDeprecated(); error UnexpectedProductId(); // Cover and payment assets error CoverAssetNotSupported(); error InvalidPaymentAsset(); error UnexpectedCoverAsset(); error UnexpectedEthSent(); error EditNotSupported(); // Price & Commission error PriceExceedsMaxPremiumInAsset(); error CommissionRateTooHigh(); // ETH transfers error InsufficientEthSent(); error SendingEthToPoolFailed(); error SendingEthToCommissionDestinationFailed(); error ReturningEthRemainderToSenderFailed(); // Misc error ExpiredCoversCannotBeEdited(); error CoverNotYetExpired(uint coverId); error InsufficientCoverAmountAllocated(); error UnexpectedPoolId(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "@openzeppelin/contracts-v4/token/ERC721/IERC721.sol"; interface ICoverNFT is IERC721 { function isApprovedOrOwner(address spender, uint tokenId) external returns (bool); function mint(address to) external returns (uint tokenId); function changeOperator(address newOperator) external; function changeNFTDescriptor(address newNFTDescriptor) external; function totalSupply() external view returns (uint); function name() external view returns (string memory); error NotOperator(); error NotMinted(); error WrongFrom(); error InvalidRecipient(); error InvalidNewOperatorAddress(); error InvalidNewNFTDescriptorAddress(); error NotAuthorized(); error UnsafeRecipient(); error AlreadyMinted(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./ICover.sol"; /* io structs */ struct ProductInitializationParams { uint productId; uint8 weight; uint96 initialPrice; uint96 targetPrice; } /* storage structs */ struct Product { uint16 productType; address yieldTokenAddress; // cover assets bitmap. each bit represents whether the asset with // the index of that bit is enabled as a cover asset for this product uint32 coverAssets; uint16 initialPriceRatio; uint16 capacityReductionRatio; bool isDeprecated; bool useFixedPrice; } struct ProductType { uint8 claimMethod; uint32 gracePeriod; } interface ICoverProducts { /* storage structs */ struct Metadata { string ipfsHash; uint timestamp; } /* io structs */ struct ProductParam { string productName; uint productId; string ipfsMetadata; Product product; uint[] allowedPools; } struct ProductTypeParam { string productTypeName; uint productTypeId; string ipfsMetadata; ProductType productType; } /* ========== VIEWS ========== */ function getProductType(uint productTypeId) external view returns (ProductType memory); function getProductTypeName(uint productTypeId) external view returns (string memory); function getProductTypeCount() external view returns (uint); function getProductTypes() external view returns (ProductType[] memory); function getProduct(uint productId) external view returns (Product memory); function getProductName(uint productTypeId) external view returns (string memory); function getProductCount() external view returns (uint); function getProducts() external view returns (Product[] memory); // add grace period function? function getProductWithType(uint productId) external view returns (Product memory, ProductType memory); function getLatestProductMetadata(uint productId) external view returns (Metadata memory); function getLatestProductTypeMetadata(uint productTypeId) external view returns (Metadata memory); function getProductMetadata(uint productId) external view returns (Metadata[] memory); function getProductTypeMetadata(uint productTypeId) external view returns (Metadata[] memory); function getAllowedPools(uint productId) external view returns (uint[] memory _allowedPools); function getAllowedPoolsCount(uint productId) external view returns (uint); function isPoolAllowed(uint productId, uint poolId) external view returns (bool); function requirePoolIsAllowed(uint[] calldata productIds, uint poolId) external view; function getCapacityReductionRatios(uint[] calldata productIds) external view returns (uint[] memory); function getInitialPrices(uint[] calldata productIds) external view returns (uint[] memory); function prepareStakingProductsParams( ProductInitializationParams[] calldata params ) external returns ( ProductInitializationParams[] memory validatedParams ); /* === MUTATIVE FUNCTIONS ==== */ function setProductTypes(ProductTypeParam[] calldata productTypes) external; function setProducts(ProductParam[] calldata params) external; /* ========== EVENTS ========== */ event ProductSet(uint id); event ProductTypeSet(uint id); // Products and product types error ProductNotFound(); error ProductTypeNotFound(); error ProductDeprecated(); error PoolNotAllowedForThisProduct(uint productId); error StakingPoolDoesNotExist(); error MismatchedArrayLengths(); error MetadataRequired(); // Misc error UnsupportedCoverAssets(); error InitialPriceRatioBelowGlobalMinPriceRatio(); error InitialPriceRatioAbove100Percent(); error CapacityReductionRatioAbove100Percent(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface IMasterAwareV2 { // TODO: if you update this enum, update lib/constants.js as well enum ID { TC, // TokenController.sol P1, // Pool.sol MR, // MemberRoles.sol MC, // MCR.sol CO, // Cover.sol SP, // StakingProducts.sol PS, // LegacyPooledStaking.sol GV, // Governance.sol GW, // LegacyGateway.sol - removed CL, // CoverMigrator.sol - removed AS, // Assessment.sol CI, // IndividualClaims.sol - Claims for Individuals CG, // YieldTokenIncidents.sol - Claims for Groups RA, // Ramm.sol ST, // SafeTracker.sol CP // CoverProducts.sol } function changeMasterAddress(address masterAddress) external; function changeDependentContractAddress() external; function internalContracts(uint) external view returns (address payable); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface IMemberRoles { enum Role {Unassigned, AdvisoryBoard, Member, Owner, Auditor} function join(address _userAddress, uint nonce, bytes calldata signature) external payable; function switchMembership(address _newAddress) external; function switchMembershipAndAssets( address newAddress, uint[] calldata coverIds, uint[] calldata stakingTokenIds ) external; function switchMembershipOf(address member, address _newAddress) external; function totalRoles() external view returns (uint256); function changeAuthorized(uint _roleId, address _newAuthorized) external; function setKycAuthAddress(address _add) external; function members(uint _memberRoleId) external view returns (uint, address[] memory memberArray); function numberOfMembers(uint _memberRoleId) external view returns (uint); function authorized(uint _memberRoleId) external view returns (address); function roles(address _memberAddress) external view returns (uint[] memory); function checkRole(address _memberAddress, uint _roleId) external view returns (bool); function getMemberLengthForAllRoles() external view returns (uint[] memory totalMembers); function memberAtIndex(uint _memberRoleId, uint index) external view returns (address, bool); function membersLength(uint _memberRoleId) external view returns (uint); event MemberRole(uint256 indexed roleId, bytes32 roleName, string roleDescription); event MemberJoined(address indexed newMember, uint indexed nonce); event switchedMembership(address indexed previousMember, address indexed newMember, uint timeStamp); event MembershipWithdrawn(address indexed member, uint timestamp); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./IPriceFeedOracle.sol"; struct SwapDetails { uint104 minAmount; uint104 maxAmount; uint32 lastSwapTime; // 2 decimals of precision. 0.01% -> 0.0001 -> 1e14 uint16 maxSlippageRatio; } struct Asset { address assetAddress; bool isCoverAsset; bool isAbandoned; } interface IPool { function swapOperator() external view returns (address); function getAsset(uint assetId) external view returns (Asset memory); function getAssets() external view returns (Asset[] memory); function transferAssetToSwapOperator(address asset, uint amount) external; function setSwapDetailsLastSwapTime(address asset, uint32 lastSwapTime) external; function getAssetSwapDetails(address assetAddress) external view returns (SwapDetails memory); function sendPayout(uint assetIndex, address payable payoutAddress, uint amount, uint ethDepositAmount) external; function sendEth(address payoutAddress, uint amount) external; function upgradeCapitalPool(address payable newPoolAddress) external; function priceFeedOracle() external view returns (IPriceFeedOracle); function getPoolValueInEth() external view returns (uint); function calculateMCRRatio(uint totalAssetValue, uint mcrEth) external pure returns (uint); function getInternalTokenPriceInAsset(uint assetId) external view returns (uint tokenPrice); function getInternalTokenPriceInAssetAndUpdateTwap(uint assetId) external returns (uint tokenPrice); function getTokenPrice() external view returns (uint tokenPrice); function getMCRRatio() external view returns (uint); function setSwapValue(uint value) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface Aggregator { function decimals() external view returns (uint8); function latestAnswer() external view returns (int); } interface IPriceFeedOracle { struct OracleAsset { Aggregator aggregator; uint8 decimals; } function ETH() external view returns (address); function assets(address) external view returns (Aggregator, uint8); function getAssetToEthRate(address asset) external view returns (uint); function getAssetForEth(address asset, uint ethIn) external view returns (uint); function getEthForAsset(address asset, uint amount) external view returns (uint); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface ISAFURAMaster { function tokenAddress() external view returns (address); function owner() external view returns (address); function emergencyAdmin() external view returns (address); function masterInitialized() external view returns (bool); function isInternal(address _add) external view returns (bool); function isPause() external view returns (bool check); function isMember(address _add) external view returns (bool); function checkIsAuthToGoverned(address _add) external view returns (bool); function getLatestAddress(bytes2 _contractName) external view returns (address payable contractAddress); function contractAddresses(bytes2 code) external view returns (address payable); function upgradeMultipleContracts( bytes2[] calldata _contractCodes, address payable[] calldata newAddresses ) external; function removeContracts(bytes2[] calldata contractCodesToRemove) external; function addNewInternalContracts( bytes2[] calldata _contractCodes, address payable[] calldata newAddresses, uint[] calldata _types ) external; function updateOwnerParameters(bytes8 code, address payable val) external; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface ISAFURAToken { function burn(uint256 amount) external returns (bool); function burnFrom(address from, uint256 value) external returns (bool); function operatorTransfer(address from, uint256 value) external returns (bool); function mint(address account, uint256 amount) external; function isLockedForMV(address member) external view returns (uint); function whiteListed(address member) external view returns (bool); function addToWhiteList(address _member) external returns (bool); function removeFromWhiteList(address _member) external returns (bool); function changeOperator(address _newOperator) external returns (bool); function lockForMemberVote(address _of, uint _days) external; /** * @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: GPL-3.0-only pragma solidity >=0.5.0; import "@openzeppelin/contracts-v4/token/ERC721/IERC721.sol"; interface IStakingNFT is IERC721 { function isApprovedOrOwner(address spender, uint tokenId) external returns (bool); function mint(uint poolId, address to) external returns (uint tokenId); function changeOperator(address newOperator) external; function changeNFTDescriptor(address newNFTDescriptor) external; function totalSupply() external returns (uint); function tokenInfo(uint tokenId) external view returns (uint poolId, address owner); function stakingPoolOf(uint tokenId) external view returns (uint poolId); function stakingPoolFactory() external view returns (address); function name() external view returns (string memory); error NotOperator(); error NotMinted(); error WrongFrom(); error InvalidRecipient(); error InvalidNewOperatorAddress(); error InvalidNewNFTDescriptorAddress(); error NotAuthorized(); error UnsafeRecipient(); error AlreadyMinted(); error NotStakingPool(); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; /* structs for io */ struct AllocationRequest { uint productId; uint coverId; uint allocationId; uint period; uint gracePeriod; bool useFixedPrice; uint previousStart; uint previousExpiration; uint previousRewardsRatio; uint globalCapacityRatio; uint capacityReductionRatio; uint rewardRatio; uint globalMinPrice; } struct BurnStakeParams { uint allocationId; uint productId; uint start; uint period; uint deallocationAmount; } interface IStakingPool { /* structs for storage */ // stakers are grouped in tranches based on the timelock expiration // tranche index is calculated based on the expiration date // the initial proposal is to have 4 tranches per year (1 tranche per quarter) struct Tranche { uint128 stakeShares; uint128 rewardsShares; } struct ExpiredTranche { uint96 accNxmPerRewardShareAtExpiry; uint96 stakeAmountAtExpiry; // nxm total supply is 6.7e24 and uint96.max is 7.9e28 uint128 stakeSharesSupplyAtExpiry; } struct Deposit { uint96 lastAccNxmPerRewardShare; uint96 pendingRewards; uint128 stakeShares; uint128 rewardsShares; } function initialize( bool isPrivatePool, uint initialPoolFee, uint maxPoolFee, uint _poolId, string memory ipfsDescriptionHash ) external; function processExpirations(bool updateUntilCurrentTimestamp) external; function requestAllocation( uint amount, uint previousPremium, AllocationRequest calldata request ) external returns (uint premium, uint allocationId); function burnStake(uint amount, BurnStakeParams calldata params) external; function depositTo( uint amount, uint trancheId, uint requestTokenId, address destination ) external returns (uint tokenId); function withdraw( uint tokenId, bool withdrawStake, bool withdrawRewards, uint[] memory trancheIds ) external returns (uint withdrawnStake, uint withdrawnRewards); function isPrivatePool() external view returns (bool); function isHalted() external view returns (bool); function manager() external view returns (address); function getPoolId() external view returns (uint); function getPoolFee() external view returns (uint); function getMaxPoolFee() external view returns (uint); function getActiveStake() external view returns (uint); function getStakeSharesSupply() external view returns (uint); function getRewardsSharesSupply() external view returns (uint); function getRewardPerSecond() external view returns (uint); function getAccNxmPerRewardsShare() external view returns (uint); function getLastAccNxmUpdate() external view returns (uint); function getFirstActiveTrancheId() external view returns (uint); function getFirstActiveBucketId() external view returns (uint); function getNextAllocationId() external view returns (uint); function getDeposit(uint tokenId, uint trancheId) external view returns ( uint lastAccNxmPerRewardShare, uint pendingRewards, uint stakeShares, uint rewardsShares ); function getTranche(uint trancheId) external view returns ( uint stakeShares, uint rewardsShares ); function getExpiredTranche(uint trancheId) external view returns ( uint accNxmPerRewardShareAtExpiry, uint stakeAmountAtExpiry, uint stakeShareSupplyAtExpiry ); function setPoolFee(uint newFee) external; function setPoolPrivacy(bool isPrivatePool) external; function getActiveAllocations( uint productId ) external view returns (uint[] memory trancheAllocations); function getTrancheCapacities( uint productId, uint firstTrancheId, uint trancheCount, uint capacityRatio, uint reductionRatio ) external view returns (uint[] memory trancheCapacities); /* ========== EVENTS ========== */ event StakeDeposited(address indexed user, uint256 amount, uint256 trancheId, uint256 tokenId); event DepositExtended(address indexed user, uint256 tokenId, uint256 initialTrancheId, uint256 newTrancheId, uint256 topUpAmount); event PoolPrivacyChanged(address indexed manager, bool isPrivate); event PoolFeeChanged(address indexed manager, uint newFee); event PoolDescriptionSet(string ipfsDescriptionHash); event Withdraw(address indexed user, uint indexed tokenId, uint tranche, uint amountStakeWithdrawn, uint amountRewardsWithdrawn); event StakeBurned(uint amount); event Deallocated(uint productId); event BucketExpired(uint bucketId); event TrancheExpired(uint trancheId); // Auth error OnlyCoverContract(); error OnlyStakingProductsContract(); error OnlyManager(); error PrivatePool(); error SystemPaused(); error PoolHalted(); // Fees error PoolFeeExceedsMax(); error MaxPoolFeeAbove100(); // Voting error NxmIsLockedForGovernanceVote(); error ManagerNxmIsLockedForGovernanceVote(); // Deposit error InsufficientDepositAmount(); error RewardRatioTooHigh(); // Staking NFTs error InvalidTokenId(); error NotTokenOwnerOrApproved(); error InvalidStakingPoolForToken(); // Tranche & capacity error NewTrancheEndsBeforeInitialTranche(); error RequestedTrancheIsNotYetActive(); error RequestedTrancheIsExpired(); error InsufficientCapacity(); // Allocation error AlreadyDeallocated(uint allocationId); }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IStakingPoolBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function stakingPoolImplementation() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; interface IStakingPoolFactory { function stakingPoolCount() external view returns (uint); function beacon() external view returns (address); function create(address beacon) external returns (uint poolId, address stakingPoolAddress); event StakingPoolCreated(uint indexed poolId, address indexed stakingPoolAddress); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.5.0; import "./ISAFURAToken.sol"; interface ITokenController { struct StakingPoolNXMBalances { uint128 rewards; uint128 deposits; } struct CoverInfo { uint16 claimCount; bool hasOpenClaim; bool hasAcceptedClaim; uint96 requestedPayoutAmount; // note: still 128 bits available here, can be used later } struct StakingPoolOwnershipOffer { address proposedManager; uint96 deadline; } function coverInfo(uint id) external view returns ( uint16 claimCount, bool hasOpenClaim, bool hasAcceptedClaim, uint96 requestedPayoutAmount ); function withdrawCoverNote( address _of, uint[] calldata _coverIds, uint[] calldata _indexes ) external; function changeOperator(address _newOperator) external; function operatorTransfer(address _from, address _to, uint _value) external returns (bool); function burnFrom(address _of, uint amount) external returns (bool); function addToWhitelist(address _member) external; function removeFromWhitelist(address _member) external; function mint(address _member, uint _amount) external; function lockForMemberVote(address _of, uint _days) external; function withdrawClaimAssessmentTokens(address[] calldata users) external; function getLockReasons(address _of) external view returns (bytes32[] memory reasons); function totalSupply() external view returns (uint); function totalBalanceOf(address _of) external view returns (uint amount); function totalBalanceOfWithoutDelegations(address _of) external view returns (uint amount); function getTokenPrice() external view returns (uint tokenPrice); function token() external view returns (ISAFURAToken); function getStakingPoolManager(uint poolId) external view returns (address manager); function getManagerStakingPools(address manager) external view returns (uint[] memory poolIds); function isStakingPoolManager(address member) external view returns (bool); function getStakingPoolOwnershipOffer(uint poolId) external view returns (address proposedManager, uint deadline); function transferStakingPoolsOwnership(address from, address to) external; function assignStakingPoolManager(uint poolId, address manager) external; function createStakingPoolOwnershipOffer(uint poolId, address proposedManager, uint deadline) external; function acceptStakingPoolOwnershipOffer(uint poolId) external; function cancelStakingPoolOwnershipOffer(uint poolId) external; function mintStakingPoolNXMRewards(uint amount, uint poolId) external; function burnStakingPoolNXMRewards(uint amount, uint poolId) external; function depositStakedNXM(address from, uint amount, uint poolId) external; function withdrawNXMStakeAndRewards(address to, uint stakeToWithdraw, uint rewardsToWithdraw, uint poolId) external; function burnStakedNXM(uint amount, uint poolId) external; function stakingPoolNXMBalances(uint poolId) external view returns(uint128 rewards, uint128 deposits); function tokensLocked(address _of, bytes32 _reason) external view returns (uint256 amount); function getWithdrawableCoverNotes( address coverOwner ) external view returns ( uint[] memory coverIds, bytes32[] memory lockReasons, uint withdrawableAmount ); function getPendingRewards(address member) external view returns (uint); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.18; /** * @dev Simple library that defines min, max and babylonian sqrt functions */ library Math { function min(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } function max(uint a, uint b) internal pure returns (uint) { return a > b ? a : b; } function sum(uint[] memory items) internal pure returns (uint) { uint count = items.length; uint total; for (uint i = 0; i < count; i++) { total += items[i]; } return total; } function divRound(uint a, uint b) internal pure returns (uint) { return (a + b / 2) / b; } function divCeil(uint a, uint b) internal pure returns (uint) { return (a + b - 1) / b; } function roundUp(uint a, uint b) internal pure returns (uint) { return divCeil(a, b) * b; } // babylonian method function sqrt(uint y) internal pure returns (uint) { if (y > 3) { uint z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } return z; } if (y != 0) { return 1; } return 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; /** * @dev Wrappers over Solidity's uintXX casting operators with added overflow * checks. * * Downcasting from uint256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeUintCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { require(value < 2**248, "SafeCast: value doesn\'t fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { require(value < 2**240, "SafeCast: value doesn\'t fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { require(value < 2**232, "SafeCast: value doesn\'t fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value < 2**224, "SafeCast: value doesn\'t fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { require(value < 2**216, "SafeCast: value doesn\'t fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { require(value < 2**208, "SafeCast: value doesn\'t fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { require(value < 2**200, "SafeCast: value doesn\'t fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { require(value < 2**192, "SafeCast: value doesn\'t fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { require(value < 2**184, "SafeCast: value doesn\'t fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { require(value < 2**176, "SafeCast: value doesn\'t fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { require(value < 2**168, "SafeCast: value doesn\'t fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { require(value < 2**160, "SafeCast: value doesn\'t fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { require(value < 2**152, "SafeCast: value doesn\'t fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { require(value < 2**144, "SafeCast: value doesn\'t fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { require(value < 2**136, "SafeCast: value doesn\'t fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { require(value < 2**120, "SafeCast: value doesn\'t fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { require(value < 2**112, "SafeCast: value doesn\'t fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { require(value < 2**104, "SafeCast: value doesn\'t fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value < 2**96, "SafeCast: value doesn\'t fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { require(value < 2**88, "SafeCast: value doesn\'t fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { require(value < 2**80, "SafeCast: value doesn\'t fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { require(value < 2**56, "SafeCast: value doesn\'t fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { require(value < 2**48, "SafeCast: value doesn\'t fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { require(value < 2**40, "SafeCast: value doesn\'t fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { require(value < 2**24, "SafeCast: value doesn\'t fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.18; /** * @dev Simple library to derive the staking pool address from the pool id without external calls */ library StakingPoolLibrary { function getAddress(address factory, uint poolId) internal pure returns (address) { bytes32 hash = keccak256( abi.encodePacked( hex'ff', factory, poolId, // salt // init code hash of the MinimalBeaconProxy // updated using patch-staking-pool-library.js script hex'1eb804b66941a2e8465fa0951be9c8b855b7794ee05b0789ab22a02ee1298ebe' // init code hash ) ); // cast last 20 bytes of hash to address return address(uint160(uint(hash))); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract ABI
API[{"inputs":[{"internalType":"contract ICoverNFT","name":"_coverNFT","type":"address"},{"internalType":"contract IStakingNFT","name":"_stakingNFT","type":"address"},{"internalType":"contract ICompleteStakingPoolFactory","name":"_stakingPoolFactory","type":"address"},{"internalType":"address","name":"_stakingPoolImplementation","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CommissionRateTooHigh","type":"error"},{"inputs":[],"name":"CoverAmountIsZero","type":"error"},{"inputs":[],"name":"CoverAssetNotSupported","type":"error"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"name":"CoverNotYetExpired","type":"error"},{"inputs":[],"name":"CoverOutsideOfTheGracePeriod","type":"error"},{"inputs":[],"name":"CoverPeriodTooLong","type":"error"},{"inputs":[],"name":"CoverPeriodTooShort","type":"error"},{"inputs":[],"name":"EditNotSupported","type":"error"},{"inputs":[],"name":"ExpiredCoversCannotBeEdited","type":"error"},{"inputs":[],"name":"InsufficientCoverAmountAllocated","type":"error"},{"inputs":[],"name":"InsufficientEthSent","type":"error"},{"inputs":[],"name":"InvalidPaymentAsset","type":"error"},{"inputs":[],"name":"OnlyOwnerOrApproved","type":"error"},{"inputs":[],"name":"PriceExceedsMaxPremiumInAsset","type":"error"},{"inputs":[],"name":"ProductDeprecated","type":"error"},{"inputs":[],"name":"ProductNotFound","type":"error"},{"inputs":[],"name":"ReturningEthRemainderToSenderFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"RevertedWithoutReason","type":"error"},{"inputs":[],"name":"SendingEthToCommissionDestinationFailed","type":"error"},{"inputs":[],"name":"SendingEthToPoolFailed","type":"error"},{"inputs":[],"name":"UnexpectedCoverAsset","type":"error"},{"inputs":[],"name":"UnexpectedEthSent","type":"error"},{"inputs":[],"name":"UnexpectedPoolId","type":"error"},{"inputs":[],"name":"UnexpectedProductId","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"coverId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"productId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"segmentId","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"string","name":"ipfsMetadata","type":"string"}],"name":"CoverEdited","type":"event"},{"inputs":[],"name":"GLOBAL_MIN_PRICE_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_COMMISSION_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NXM_PER_ALLOCATION_UNIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"activeCover","outputs":[{"internalType":"uint192","name":"totalActiveCoverInAsset","type":"uint192"},{"internalType":"uint64","name":"lastBucketUpdateId","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"},{"internalType":"uint256","name":"segmentId","type":"uint256"},{"internalType":"uint256","name":"payoutAmountInAsset","type":"uint256"}],"name":"burnStake","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"coverId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"coverAsset","type":"uint8"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint256","name":"maxPremiumInAsset","type":"uint256"},{"internalType":"uint8","name":"paymentAsset","type":"uint8"},{"internalType":"uint16","name":"commissionRatio","type":"uint16"},{"internalType":"address","name":"commissionDestination","type":"address"},{"internalType":"string","name":"ipfsData","type":"string"}],"internalType":"struct BuyCoverParams","name":"params","type":"tuple"},{"components":[{"internalType":"uint40","name":"poolId","type":"uint40"},{"internalType":"bool","name":"skip","type":"bool"},{"internalType":"uint256","name":"coverAmountInAsset","type":"uint256"}],"internalType":"struct PoolAllocationRequest[]","name":"poolAllocationRequests","type":"tuple[]"}],"name":"buyCover","outputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_coverNFTDescriptor","type":"address"}],"name":"changeCoverNFTDescriptor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"changeDependentContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"masterAddress","type":"address"}],"name":"changeMasterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_stakingNFTDescriptor","type":"address"}],"name":"changeStakingNFTDescriptor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"changeStakingPoolFactoryOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"name":"coverData","outputs":[{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"coverAsset","type":"uint8"},{"internalType":"uint96","name":"amountPaidOut","type":"uint96"}],"internalType":"struct CoverData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coverDataCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coverNFT","outputs":[{"internalType":"contract ICoverNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"coverSegmentAllocations","outputs":[{"internalType":"uint40","name":"poolId","type":"uint40"},{"internalType":"uint96","name":"coverAmountInNXM","type":"uint96"},{"internalType":"uint96","name":"premiumInNXM","type":"uint96"},{"internalType":"uint24","name":"allocationId","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"},{"internalType":"uint256","name":"segmentId","type":"uint256"}],"name":"coverSegmentWithRemainingAmount","outputs":[{"components":[{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint32","name":"start","type":"uint32"},{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint32","name":"gracePeriod","type":"uint32"},{"internalType":"uint24","name":"globalRewardsRatio","type":"uint24"},{"internalType":"uint24","name":"globalCapacityRatio","type":"uint24"}],"internalType":"struct CoverSegment","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"name":"coverSegments","outputs":[{"components":[{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"uint32","name":"start","type":"uint32"},{"internalType":"uint32","name":"period","type":"uint32"},{"internalType":"uint32","name":"gracePeriod","type":"uint32"},{"internalType":"uint24","name":"globalRewardsRatio","type":"uint24"},{"internalType":"uint24","name":"globalCapacityRatio","type":"uint24"}],"internalType":"struct CoverSegment[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"name":"coverSegmentsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverId","type":"uint256"}],"name":"expireCover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getGlobalCapacityAndPriceRatios","outputs":[{"internalType":"uint256","name":"_globalCapacityRatio","type":"uint256"},{"internalType":"uint256","name":"_globalMinPriceRatio","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getGlobalCapacityRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getGlobalMinPriceRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getGlobalRewardsRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"internalContracts","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"master","outputs":[{"internalType":"contract ISAFURAMaster","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverAsset","type":"uint256"}],"name":"recalculateActiveCoverInAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingNFT","outputs":[{"internalType":"contract IStakingNFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"poolId","type":"uint256"}],"name":"stakingPool","outputs":[{"internalType":"contract IStakingPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingPoolFactory","outputs":[{"internalType":"contract ICompleteStakingPoolFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingPoolImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"}],"name":"totalActiveCoverInAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"coverAsset","type":"uint256"}],"name":"updateTotalActiveCoverAmount","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620043b7380380620043b7833981016040819052620000359162000076565b60016002556001600160a01b0393841660805291831660a052821660c0521660e052620000de565b6001600160a01b03811681146200007357600080fd5b50565b600080600080608085870312156200008d57600080fd5b84516200009a816200005d565b6020860151909450620000ad816200005d565b6040860151909350620000c0816200005d565b6060860151909250620000d3816200005d565b939692955090935050565b60805160a05160c05160e05161426e6200014960003960006102ab0152600081816104d501528181610a6201526110cd0152600081816102050152610bb901526000818161039801528181610c1d01528181610ec60152818161194701526121ba015261426e6000f3fe6080604052600436106101ee5760003560e01c8063a1b8adcb1161010d578063da30105e116100a0578063ee97f7f31161006f578063ee97f7f3146106fa578063f4136f7f1461071a578063f480b7b91461073a578063f657963214610770578063ffb681741461078357600080fd5b8063da30105e1461066b578063dd9bce3f1461068b578063eb962360146106a1578063ed258005146106d757600080fd5b8063c96d2fa7116100dc578063c96d2fa7146105e9578063cccf4d4a146105fe578063ccfa4b791461061e578063d46655f41461064b57600080fd5b8063a1b8adcb146104c3578063ac9650d8146104f7578063b6b9869614610524578063bce2a8831461053957600080fd5b80634146f14e1161018557806377e4d59e1161015457806377e4d59e1461044157806378b4f6061461046e57806378d06995146104835780638aaff34a146104a357600080fd5b80634146f14e1461037157806342e53fcf1461038657806362467ca4146103ba578063638233081461041457600080fd5b80632aa8195e116101c15780632aa8195e1461029957806330dc2a82146102cd5780633d1c7197146102ed578063404730f41461035c57600080fd5b80630ce71e32146101f35780630ea9c984146102445780631246da391461025b57806321b0b0cb14610279575b600080fd5b3480156101ff57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561025057600080fd5b50610259610798565b005b34801561026757600080fd5b5060645b60405190815260200161023b565b34801561028557600080fd5b5061022761029436600461371f565b610a4a565b3480156102a557600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d957600080fd5b506102596102e836600461375d565b610aea565b3480156102f957600080fd5b5061033561030836600461371f565b6009602052600090815260409020546001600160c01b03811690600160c01b90046001600160401b031682565b604080516001600160c01b0390931683526001600160401b0390911660208301520161023b565b34801561036857600080fd5b5061026b610c19565b34801561037d57600080fd5b5061026b610ca2565b34801561039257600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c657600080fd5b506103da6103d536600461377a565b610cb8565b6040805164ffffffffff9590951685526001600160601b039384166020860152919092169083015262ffffff16606082015260800161023b565b34801561042057600080fd5b5061026b61042f36600461371f565b60009081526008602052604090205490565b34801561044d57600080fd5b5061046161045c36600461371f565b610d23565b60405161023b9190613802565b34801561047a57600080fd5b50614e2061026b565b34801561048f57600080fd5b5061025961049e36600461371f565b610def565b3480156104af57600080fd5b506102596104be36600461375d565b610e00565b3480156104cf57600080fd5b506102277f000000000000000000000000000000000000000000000000000000000000000081565b34801561050357600080fd5b50610517610512366004613850565b610ef5565b60405161023b9190613914565b34801561053057600080fd5b5061025961103a565b34801561054557600080fd5b506105b661055436600461371f565b6040805160608082018352600080835260208084018290529284018190529384526005825292829020825193840183525462ffffff811684526301000000810460ff169184019190915264010000000090046001600160601b03169082015290565b60408051825162ffffff16815260208084015160ff1690820152918101516001600160601b03169082015260600161023b565b3480156105f557600080fd5b5061026b606481565b34801561060a57600080fd5b5061025961061936600461371f565b6110fe565b34801561062a57600080fd5b5061063e610639366004613976565b6111e5565b60405161023b9190613998565b34801561065757600080fd5b5061025961066636600461375d565b6112f7565b34801561067757600080fd5b5061022761068636600461377a565b611371565b34801561069757600080fd5b5061026b610bb881565b3480156106ad57600080fd5b506102276106bc36600461371f565b6001602052600090815260409020546001600160a01b031681565b3480156106e357600080fd5b5060408051614e208152606460208201520161023b565b34801561070657600080fd5b50600054610227906001600160a01b031681565b34801561072657600080fd5b5061025961073536600461371f565b6119c8565b34801561074657600080fd5b5061026b61075536600461371f565b6000908152600960205260409020546001600160c01b031690565b61026b61077e366004613c1c565b611cd1565b34801561078f57600080fd5b5061138861026b565b6000546040516227050b60e31b815261503160f01b60048201526001600160a01b0390911690630138285890602401602060405180830381865afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108089190613d50565b600160008181526020919091527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b815261544360f01b6004820152911690630138285890602401602060405180830381865afa158015610893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b79190613d50565b600080805260016020527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4980546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b81526126a960f11b6004820152911690630138285890602401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190613d50565b60026000908152600160205260008051602061421983398151915280546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b815261043560f41b6004820152911690630138285890602401602060405180830381865afa1580156109db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ff9190613d50565b600f60005260016020527f12bd632ff333b55931f9f8bda8b4ed27e86687f88c95871969d72474fb428c1480546001600160a01b0319166001600160a01b0392909216919091179055565b604080516001600160f81b03196020808301919091527f000000000000000000000000000000000000000000000000000000000000000060601b6bffffffffffffffffffffffff19166021830152603582018490527f1eb804b66941a2e8465fa0951be9c8b855b7794ee05b0789ab22a02ee1298ebe60558084019190915283518084039091018152607590920190925280519101206000905b92915050565b6002600052600160208190526000805160206142198339815191525460405163505ef22f60e01b815233600482015260248101929092526001600160a01b03169063505ef22f90604401602060405180830381865afa158015610b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b759190613d78565b610b9a5760405162461bcd60e51b8152600401610b9190613d95565b60405180910390fd5b604051639d8168eb60e01b81526001600160a01b0382811660048301527f00000000000000000000000000000000000000000000000000000000000000001690639d8168eb906024015b600060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613ddb565b905090565b610cb56064670de0b6b3a7640000613e0a565b81565b60066020528260005260406000206020528160005260406000208181548110610ce057600080fd5b60009182526020909120015464ffffffffff811693506001600160601b03600160281b820481169350600160881b820416915062ffffff600160e81b9091041684565b606060086000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610de45760008481526020908190206040805160c081018252918501546001600160601b038116835263ffffffff600160601b8204811684860152600160801b8204811692840192909252600160a01b8104909116606083015262ffffff600160c01b820481166080840152600160d81b9091041660a0820152825260019092019101610d58565b505050509050919050565b610dfd8160008060006125a8565b50565b6002600052600160208190526000805160206142198339815191525460405163505ef22f60e01b815233600482015260248101929092526001600160a01b03169063505ef22f90604401602060405180830381865afa158015610e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8b9190613d78565b610ea75760405162461bcd60e51b8152600401610b9190613d95565b604051639d8168eb60e01b81526001600160a01b0382811660048301527f00000000000000000000000000000000000000000000000000000000000000001690639d8168eb90602401610be4565b606081806001600160401b03811115610f1057610f106139a6565b604051908082528060200260200182016040528015610f4357816020015b6060815260200190600190039081610f2e5790505b50915060005b818110156110325760008030878785818110610f6757610f67613e2c565b9050602002810190610f799190613e42565b604051610f87929190613e8f565b600060405180830381855af49150503d8060008114610fc2576040519150601f19603f3d011682016040523d82523d6000602084013e610fc7565b606091505b509150915081610fff5780516000819003610ff85760405163f1a8c42d60e01b815260048101859052602401610b91565b8060208301fd5b8085848151811061101257611012613e2c565b60200260200101819052505050808061102a90613e9f565b915050610f49565b505092915050565b600080546040516227050b60e31b815261053560f41b60048201526001600160a01b0390911690630138285890602401602060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ab9190613d50565b6040516306394c9b60e01b81526001600160a01b0380831660048301529192507f0000000000000000000000000000000000000000000000000000000000000000909116906306394c9b90602401610be4565b600061110d62093a8042613e0a565b90506000806111236301e1338062093a806126f1565b905060015b81811161117857600061113b8286613eb8565b6000878152600a602090815260408083208484529091529020549091506111629085613eb8565b935050808061117090613e9f565b915050611128565b50604051806040016040528061118d84612714565b6001600160c01b031681526020016111a48561277d565b6001600160401b0390811690915260009586526009602090815260409096208251929096015116600160c01b026001600160c01b0390911617909355505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152600083815260086020526040812080548490811061123757611237613e2c565b600091825260208083206040805160c08101825291909301546001600160601b03808216835263ffffffff600160601b8304811684860152600160801b8304811684870152600160a01b830416606084015262ffffff600160c01b830481166080850152600160d81b90920490911660a08301528885526005909252919092205481519193506401000000009004821691168111156112d75760006112e4565b81516112e4908290613ecb565b6001600160601b03168252509392505050565b6000546001600160a01b03161561134f576000546001600160a01b0316331461134f5760405162461bcd60e51b815260206004820152600a6024820152692737ba1036b0b9ba32b960b11b6044820152606401610b91565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516323c5b10760e21b81523360048201526001600160a01b0390911690638f16c41c90602401602060405180830381865afa1580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190613d78565b6114355760405162461bcd60e51b815260206004820152602260248201527f43616c6c6572206973206e6f7420616e20696e7465726e616c20636f6e74726160448201526118dd60f21b6064820152608401610b91565b600084815260056020908152604080832080546301000000900460ff16845260099092528220909161146787876111e5565b60008881526006602090815260408083208a84529091528120855485549394509092630100000090910460ff1691600160c01b9091046001600160401b0316906114b462093a8042613e0a565b905060006114de866040015187602001516114cf9190613ef2565b63ffffffff1662093a806126f1565b905060006114ed8585856127e6565b90508282111561156a5760006115108c89600001516001600160601b0316612828565b905061151c8183613eb8565b915061152781612714565b6001600160c01b0316600a6000888152602001908152602001600020600085815260200190815260200160002060008282546115639190613f0f565b9091555050505b61157381612714565b8854899060009061158e9084906001600160c01b0316613f22565b92506101000a8154816001600160c01b0302191690836001600160c01b031602179055506115bb8361277d565b88546001600160401b0391909116600160c01b026001600160c01b03909116178855506115ee935089925061283e915050565b8454859060049061161190849064010000000090046001600160601b0316613f42565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060005b815481101561193057600082828154811061165557611655613e2c565b6000918252602080832060408051608081018252919093015464ffffffffff811682526001600160601b03600160281b82048116938301849052600160881b820481169483019490945262ffffff600160e81b9091041660608201528751909450909116906116c5908b90613f62565b6116cf9190613e0a565b905060008560a0015162ffffff16612710836116eb9190613f62565b6116f59190613e0a565b90506117008261283e565b85858154811061171257611712613e2c565b6000918252602090912001805460059061173d908490600160281b90046001600160601b0316613ecb565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555061179a86600001516001600160601b03168b85604001516001600160601b031661178b9190613f62565b6117959190613e0a565b61283e565b8585815481106117ac576117ac613e2c565b600091825260209091200180546011906117d7908490600160881b90046001600160601b0316613ecb565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060006040518060a00160405280856060015162ffffff1681526020018a60000160009054906101000a900462ffffff1662ffffff168152602001886020015163ffffffff168152602001886040015163ffffffff168152602001848152509050600086868154811061186f5761186f613e2c565b60009182526020909120015464ffffffffff16905061188d81610a4a565b60408051632e28698360e01b815260048101869052845160248201526020850151604482015290840151606482015260608401516084820152608084015160a48201526001600160a01b039190911690632e2869839060c401600060405180830381600087803b15801561190057600080fd5b505af1158015611914573d6000803e3d6000fd5b505050505050505050808061192890613e9f565b915050611638565b506040516331a9108f60e11b8152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015611996573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ba9190613d50565b9450505050505b9392505050565b6000818152600860205260408120546119e390600190613f0f565b905060006119f183836111e5565b60008481526005602090815260408083208151606081018352905462ffffff811682526301000000810460ff168285015264010000000090046001600160601b031681830152908401519184015193945092611a4d9190613ef2565b63ffffffff16905042811115611a7957604051637f65db9f60e11b815260048101869052602401610b91565b60005b6000868152600660209081526040808320888452909152902054811015611bf75760008681526006602090815260408083208884529091528120805483908110611ac857611ac8613e2c565b600091825260209182902060408051608081018252929091015464ffffffffff81168352600160281b81046001600160601b0390811694840194909452600160881b810490931690820152600160e81b90910462ffffff1660608201529050611b2f6136b5565b845162ffffff90811682526060830151166040820152602086015163ffffffff1660c082015260e081018490528151611b6e9064ffffffffff16610a4a565b6001600160a01b031663a7d4d7e4600080846040518463ffffffff1660e01b8152600401611b9e93929190614005565b60408051808303816000875af1158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190614021565b505050508080611bef90613e9f565b915050611a7c565b506000611c0762093a8042613e0a565b90506000611c188362093a806126f1565b905080821015611cc857845160208086015160ff166000908152600a8252604080822085835290925290812080546001600160601b0390931692909190611c60908490613f0f565b9091555050845160208086015160ff16600090815260099091526040812080546001600160601b0390931692909190611ca39084906001600160c01b0316613f22565b92506101000a8154816001600160c01b0302191690836001600160c01b031602179055505b50505050505050565b6002600081815260016020526000805160206142198339815191525460405163505ef22f60e01b8152336004820152602481019390935290916001600160a01b039091169063505ef22f90604401602060405180830381865afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d609190613d78565b611da55760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b2b6b132b960511b6044820152606401610b91565b6002805403611df65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b91565b6002805560005460408051600162f6c75960e01b0319815290516001600160a01b039092169163ff0938a7916004808201926020929091908290030181865afa158015611e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6b9190613d78565b15611eab5760405162461bcd60e51b815260206004820152601060248201526f14de5cdd195b481a5cc81c185d5cd95960821b6044820152606401610b91565b6224ea008360a0015163ffffffff161015611ed95760405163056d6c0b60e11b815260040160405180910390fd5b6301e133808360a0015163ffffffff161115611f085760405163a15784c760e01b815260040160405180910390fd5b610bb883610100015161ffff161115611f3457604051636bdaa48360e11b815260040160405180910390fd5b82608001516001600160601b0316600003611f6257604051636e36642760e11b815260040160405180910390fd5b826060015160ff168360e0015160ff1614158015611f88575060e083015160ff90811614155b15611fa6576040516304b4a0b760e51b815260040160405180910390fd5b6000611fb06136b5565b6000611fba6128a2565b9050856040015162ffffff16816001600160a01b0316634a348da96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612004573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120289190613ddb565b11612046576040516379de4af560e01b815260040160405180910390fd5b60408087015190516302db1c0360e61b815262ffffff909116600482015260009081906001600160a01b0384169063b6c700c09060240161012060405180830381865afa15801561209b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bf91906140b4565b915091508160a00151156120e657604051631340cecb60e21b815260040160405180910390fd5b612101886060015160ff16836040015163ffffffff166128c9565b61211e57604051637548463d60e01b815260040160405180910390fd5b604088015162ffffff168452602080850187905260a0808a015163ffffffff9081166060880152929091015190911660808086019190915260c0830151151591850191909152614e20610120850152015161ffff16610140830152506113886101608201526064610180820152845160009081036122be5760208601516040516335313c2160e11b81526001600160a01b0391821660048201527f000000000000000000000000000000000000000000000000000000000000000090911690636a627842906024016020604051808303816000875af1158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190613ddb565b60408051606080820183528983015162ffffff9081168352908a015160ff9081166020808501918252600085870181815288825260059092529590952093518454915195516001600160601b0316640100000000026fffffffffffffffffffffffff00000000199690931663010000000263ffffffff19909216931692909217919091179290921691909117905593506122d7565b60405163d0dca47b60e01b815260040160405180910390fd5b60006122e161297f565b6060880151604051631d76154960e31b815260ff90911660048201526001600160a01b03919091169063ebb0aa48906024016020604051808303816000875af1158015612332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123569190613ddb565b60208401869052905060008061236e8589858961298a565b9150915088608001516001600160601b03168210156123a0576040516304508f7760e41b815260040160405180910390fd5b600860008881526020019081526020016000206040518060c001604052806123c78561283e565b6001600160601b031681526020016123de42612ef8565b63ffffffff1681526020018b60a0015163ffffffff1681526020016124068860800151612ef8565b63ffffffff16815260200161241c611388612f5d565b62ffffff168152602001612431614e20612f5d565b62ffffff90811690915282546001810184556000938452602093849020835191018054948401516040850151606080870151608088015160a0988901518816600160d81b0262ffffff60d81b1991909816600160c01b021665ffffffffffff60c01b1963ffffffff928316600160a01b0263ffffffff60a01b19958416600160801b029590951667ffffffffffffffff60801b19968416600160601b026fffffffffffffffffffffffffffffffff19909c166001600160601b03909916989098179a909a17949094169590951791909117969096161792909217909155918b0151908b01516125299260ff90921691859116876125a8565b61254c818a60e0015160ff16858c60c001518d61010001518e6101200151612fc1565b85896040015162ffffff16887f3da7af757f7e475ca8192a0ff54890cc9d744e04ecd45be53e8bfee6c93d2de2338d610140015160405161258e929190614171565b60405180910390a450506001600255509295945050505050565b60008481526009602090815260408083208151808301909252546001600160c01b0381168252600160c01b90046001600160401b031691810191909152906125f362093a8042613e0a565b82519091506001600160c01b0316801561262c5761261f8784602001516001600160401b0316846127e6565b6126299082613f0f565b90505b6126368482613f0f565b90506126428682613eb8565b905061264d8261277d565b6001600160401b0316602084015261266481612714565b6001600160c01b039081168452600088815260096020908152604082208651918701516001600160401b0316600160c01b0291909316179091556126b46126ab8742613eb8565b62093a806126f1565b6000898152600a602090815260408083208484529091528120805492935089929091906126e2908490613eb8565b90915550505050505050505050565b60008160016127008286613eb8565b61270a9190613f0f565b6119c19190613e0a565b6000600160c01b82106127795760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663932206269747360c81b6064820152608401610b91565b5090565b60006801000000000000000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610b91565b60005b818310156119c1576127fa83613e9f565b6000858152600a602090815260408083208484529091529020549093506128219082613eb8565b90506127e9565b600081831061283757816119c1565b5090919050565b6000600160601b82106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201526536206269747360d01b6064820152608401610b91565b6000600181600f5b81526020810191909152604001600020546001600160a01b0316919050565b600081158015906128dd57506001831b8216155b156128ea57506000610ae4565b60006128f461297f565b6001600160a01b031663eac8f5b8856040518263ffffffff1660e01b815260040161292191815260200190565b606060405180830381865afa15801561293e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129629190614195565b90508060200151801561297757508060400151155b949350505050565b6000600181816128aa565b600080600060405180608001604052806000815260200160008152602001600081526020016000815250905060008085116129c65760006129f8565b6020808901516000908152600690915260408120906129e6600188613f0f565b81526020810191909152604001600020545b825260005b8751811015612ecd578251811015612c49576020808a0151600090815260069091526040812081612a2f60018a613f0f565b81526020019081526020016000208281548110612a4e57612a4e613e2c565b600091825260209182902060408051608081018252929091015464ffffffffff81168352600160281b81046001600160601b0390811694840194909452600160881b810490931690820152600160e81b90910462ffffff1660608201528951909150899083908110612ac257612ac2613e2c565b60200260200101516000015164ffffffffff16816000015164ffffffffff1614612aff5760405163034007f360e31b815260040160405180910390fd5b888281518110612b1157612b11613e2c565b60200260200101516020015115612bd3576020808b015160009081526006825260408082208a835283528082208054600181018255908352918390208451920180549385015191850151606086015162ffffff16600160e81b026001600160e81b036001600160601b03928316600160881b02166001600160881b0392909416600160281b81026001600160881b031990971664ffffffffff9096169590951795909517169190911792909217909155612bcb9084613eb8565b925050612ebb565b60408101516001600160601b0316602085015260c08a015160e08b0151612bfa9190613f0f565b428b60e00151612c0a9190613f0f565b82604001516001600160601b0316612c229190613f62565b612c2c9190613e0a565b60408086019190915260609091015162ffffff16908a0152612c51565b600060408a01525b6000612ca8612c90670de0b6b3a76400008b8581518110612c7457612c74613e2c565b602002602001015160400151612c8a9190613f62565b8a6126f1565b612ca36064670de0b6b3a7640000613e0a565b613448565b9050600080612cda8b8581518110612cc257612cc2613e2c565b60200260200101516000015164ffffffffff16610a4a565b6001600160a01b031663a7d4d7e48488602001518f6040518463ffffffff1660e01b8152600401612d0d93929190614005565b60408051808303816000875af1158015612d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4f9190614021565b9150915082600014612e7c57600660008d60200151815260200190815260200160002060008a815260200190815260200160002060405180608001604052808d8781518110612da057612da0613e2c565b60200260200101516000015164ffffffffff168152602001612dc18661283e565b6001600160601b03168152602001612dd88561283e565b6001600160601b03168152602001612def84612f5d565b62ffffff90811690915282546001810184556000938452602093849020835191018054948401516040850151606090950151909316600160e81b026001600160e81b036001600160601b03958616600160881b02166001600160881b0395909416600160281b026001600160881b031990961664ffffffffff909316929092179490941792909216171790555b8186604001511015612e9c576040860151612e979083613f0f565b612e9f565b60005b612ea99088613eb8565b9650612eb58386613eb8565b94505050505b80612ec581613e9f565b9150506129fd565b50670de0b6b3a7640000612ee18783613f62565b612eeb9190613e0a565b9350505094509492505050565b600064010000000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610b91565b6000630100000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201526534206269747360d01b6064820152608401610b91565b8415801590612fd05750600034115b15612fee57604051630f33611760e01b815260040160405180910390fd5b60fe19850161316857600061ffff831615613037578661301461ffff8516612710613f0f565b6130206127108a613f62565b61302a9190613e0a565b6130349190613f0f565b90505b836130428289613eb8565b11156130615760405163265dbe6d60e11b815260040160405180910390fd5b600061306b61345f565b60405163079cc67960e41b8152336004820152602481018a90529091506001600160a01b038216906379cc6790906044016020604051808303816000875af11580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190613d78565b50811561316157604051630d1af10360e01b81523360048201526001600160a01b03848116602483015260448201849052821690630d1af103906064016020604051808303816000875af115801561313b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315f9190613d78565b505b5050613440565b600061317261297f565b90506000670de0b6b3a76400006131898988613f62565b6131939190613e0a565b90506000816131a861ffff8716612710613f0f565b6131b461271085613f62565b6131be9190613e0a565b6131c89190613f0f565b905060006131d68284613eb8565b9050868111156131f95760405163265dbe6d60e11b815260040160405180910390fd5b88613399578034101561321f5760405163f244866f60e01b815260040160405180910390fd5b600061322b8234613f0f565b90506000856001600160a01b03168560405160006040518083038185875af1925050503d806000811461327a576040519150601f19603f3d011682016040523d82523d6000602084013e61327f565b606091505b50509050806132a15760405163ab1ee9bf60e01b815260040160405180910390fd5b50821561331e576000866001600160a01b03168460405160006040518083038185875af1925050503d80600081146132f5576040519150601f19603f3d011682016040523d82523d6000602084013e6132fa565b606091505b505090508061331c576040516308118ce960e21b815260040160405180910390fd5b505b801561338f57604051600090339083908381818185875af1925050503d8060008114613366576040519150601f19603f3d011682016040523d82523d6000602084013e61336b565b606091505b505090508061338d576040516366abea6d60e11b815260040160405180910390fd5b505b5050505050613440565b604051631d591eb760e31b8152600481018a90526000906001600160a01b0386169063eac8f5b890602401606060405180830381865afa1580156133e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134059190614195565b5190508061341e6001600160a01b03821633888861346a565b8315613439576134396001600160a01b03821633898761346a565b5050505050505b505050505050565b60008161345584846126f1565b6119c19190613f62565b6000600181806128aa565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526134c49085906134ca565b50505050565b600061351f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135a19092919063ffffffff16565b80519091501561359c578080602001905181019061353d9190613d78565b61359c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b91565b505050565b60606129778484600085856001600160a01b0385163b6136035760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b91565b600080866001600160a01b0316858760405161361f91906141e9565b60006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b509150915061367182828661367c565b979650505050505050565b6060831561368b5750816119c1565b82511561369b5782518084602001fd5b8160405162461bcd60e51b8152600401610b919190614205565b604051806101a001604052806000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561373157600080fd5b5035919050565b6001600160a01b0381168114610dfd57600080fd5b803561375881613738565b919050565b60006020828403121561376f57600080fd5b81356119c181613738565b60008060006060848603121561378f57600080fd5b505081359360208301359350604090920135919050565b6001600160601b038151168252602081015163ffffffff80821660208501528060408401511660408501528060608401511660608501525050608081015162ffffff80821660808501528060a08401511660a085015250505050565b6020808252825182820181905260009190848201906040850190845b81811015613844576138318385516137a6565b9284019260c0929092019160010161381e565b50909695505050505050565b6000806020838503121561386357600080fd5b82356001600160401b038082111561387a57600080fd5b818501915085601f83011261388e57600080fd5b81358181111561389d57600080fd5b8660208260051b85010111156138b257600080fd5b60209290920196919550909350505050565b60005b838110156138df5781810151838201526020016138c7565b50506000910152565b600081518084526139008160208601602086016138c4565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561396957603f198886030184526139578583516138e8565b9450928501929085019060010161393b565b5092979650505050505050565b6000806040838503121561398957600080fd5b50508035926020909101359150565b60c08101610ae482846137a6565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156139de576139de6139a6565b60405290565b60405161016081016001600160401b03811182821017156139de576139de6139a6565b60405160e081016001600160401b03811182821017156139de576139de6139a6565b604051601f8201601f191681016001600160401b0381118282101715613a5157613a516139a6565b604052919050565b803562ffffff8116811461375857600080fd5b60ff81168114610dfd57600080fd5b803561375881613a6c565b80356001600160601b038116811461375857600080fd5b63ffffffff81168114610dfd57600080fd5b803561375881613a9d565b61ffff81168114610dfd57600080fd5b803561375881613aba565b600082601f830112613ae657600080fd5b81356001600160401b03811115613aff57613aff6139a6565b613b12601f8201601f1916602001613a29565b818152846020838601011115613b2757600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610dfd57600080fd5b600082601f830112613b6357600080fd5b813560206001600160401b03821115613b7e57613b7e6139a6565b613b8c818360051b01613a29565b82815260609283028501820192828201919087851115613bab57600080fd5b8387015b85811015613c0f5781818a031215613bc75760008081fd5b613bcf6139bc565b813564ffffffffff81168114613be55760008081fd5b815281860135613bf481613b44565b81870152604082810135908201528452928401928101613baf565b5090979650505050505050565b60008060408385031215613c2f57600080fd5b82356001600160401b0380821115613c4657600080fd5b908401906101608287031215613c5b57600080fd5b613c636139e4565b82358152613c736020840161374d565b6020820152613c8460408401613a59565b6040820152613c9560608401613a7b565b6060820152613ca660808401613a86565b6080820152613cb760a08401613aaf565b60a082015260c083013560c0820152613cd260e08401613a7b565b60e0820152610100613ce5818501613aca565b90820152610120613cf784820161374d565b908201526101408381013583811115613d0f57600080fd5b613d1b89828701613ad5565b828401525050809450506020850135915080821115613d3957600080fd5b50613d4685828601613b52565b9150509250929050565b600060208284031215613d6257600080fd5b81516119c181613738565b805161375881613b44565b600060208284031215613d8a57600080fd5b81516119c181613b44565b60208082526026908201527f43616c6c6572206973206e6f7420616e2061647669736f727920626f6172642060408201526536b2b6b132b960d11b606082015260800190565b600060208284031215613ded57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082613e2757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112613e5957600080fd5b8301803591506001600160401b03821115613e7357600080fd5b602001915036819003821315613e8857600080fd5b9250929050565b8183823760009101908152919050565b600060018201613eb157613eb1613df4565b5060010190565b80820180821115610ae457610ae4613df4565b6001600160601b03828116828216039080821115613eeb57613eeb613df4565b5092915050565b63ffffffff818116838216019080821115613eeb57613eeb613df4565b81810381811115610ae457610ae4613df4565b6001600160c01b03828116828216039080821115613eeb57613eeb613df4565b6001600160601b03818116838216019080821115613eeb57613eeb613df4565b8082028115828204841417610ae457610ae4613df4565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a0810151613fb860a084018215159052565b5060c0818101519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018090810151910152565b838152602081018390526101e081016129776040830184613f79565b6000806040838503121561403457600080fd5b505080516020909101519092909150565b805161375881613aba565b60006040828403121561406257600080fd5b604051604081018181106001600160401b0382111715614084576140846139a6565b8060405250809150825161409781613a6c565b815260208301516140a781613a9d565b6020919091015292915050565b6000808284036101208112156140c957600080fd5b60e08112156140d757600080fd5b506140e0613a07565b83516140eb81613aba565b815260208401516140fb81613738565b6020820152604084015161410e81613a9d565b6040820152606084015161412181613aba565b606082015261413260808501614045565b608082015261414360a08501613d6d565b60a082015261415460c08501613d6d565b60c082015291506141688460e08501614050565b90509250929050565b6001600160a01b0383168152604060208201819052600090612977908301846138e8565b6000606082840312156141a757600080fd5b6141af6139bc565b82516141ba81613738565b815260208301516141ca81613b44565b602082015260408301516141dd81613b44565b60408201529392505050565b600082516141fb8184602087016138c4565b9190910192915050565b6020815260006119c160208301846138e856fed9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330fa26469706673582212203061d10ea7b7902abc337bf0b5cf59d0f9caa941158abe95068613129c1f326d64736f6c63430008120033000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd000000000000000000000000a5190b1bf3fc95d28b739fff3bcfc106acf3863e00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d0000000000000000000000009a16908588d42f1a223ac903abd383423d154107
Deployed Bytecode
0x6080604052600436106101ee5760003560e01c8063a1b8adcb1161010d578063da30105e116100a0578063ee97f7f31161006f578063ee97f7f3146106fa578063f4136f7f1461071a578063f480b7b91461073a578063f657963214610770578063ffb681741461078357600080fd5b8063da30105e1461066b578063dd9bce3f1461068b578063eb962360146106a1578063ed258005146106d757600080fd5b8063c96d2fa7116100dc578063c96d2fa7146105e9578063cccf4d4a146105fe578063ccfa4b791461061e578063d46655f41461064b57600080fd5b8063a1b8adcb146104c3578063ac9650d8146104f7578063b6b9869614610524578063bce2a8831461053957600080fd5b80634146f14e1161018557806377e4d59e1161015457806377e4d59e1461044157806378b4f6061461046e57806378d06995146104835780638aaff34a146104a357600080fd5b80634146f14e1461037157806342e53fcf1461038657806362467ca4146103ba578063638233081461041457600080fd5b80632aa8195e116101c15780632aa8195e1461029957806330dc2a82146102cd5780633d1c7197146102ed578063404730f41461035c57600080fd5b80630ce71e32146101f35780630ea9c984146102445780631246da391461025b57806321b0b0cb14610279575b600080fd5b3480156101ff57600080fd5b506102277f000000000000000000000000a5190b1bf3fc95d28b739fff3bcfc106acf3863e81565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561025057600080fd5b50610259610798565b005b34801561026757600080fd5b5060645b60405190815260200161023b565b34801561028557600080fd5b5061022761029436600461371f565b610a4a565b3480156102a557600080fd5b506102277f0000000000000000000000009a16908588d42f1a223ac903abd383423d15410781565b3480156102d957600080fd5b506102596102e836600461375d565b610aea565b3480156102f957600080fd5b5061033561030836600461371f565b6009602052600090815260409020546001600160c01b03811690600160c01b90046001600160401b031682565b604080516001600160c01b0390931683526001600160401b0390911660208301520161023b565b34801561036857600080fd5b5061026b610c19565b34801561037d57600080fd5b5061026b610ca2565b34801561039257600080fd5b506102277f000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd81565b3480156103c657600080fd5b506103da6103d536600461377a565b610cb8565b6040805164ffffffffff9590951685526001600160601b039384166020860152919092169083015262ffffff16606082015260800161023b565b34801561042057600080fd5b5061026b61042f36600461371f565b60009081526008602052604090205490565b34801561044d57600080fd5b5061046161045c36600461371f565b610d23565b60405161023b9190613802565b34801561047a57600080fd5b50614e2061026b565b34801561048f57600080fd5b5061025961049e36600461371f565b610def565b3480156104af57600080fd5b506102596104be36600461375d565b610e00565b3480156104cf57600080fd5b506102277f00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d81565b34801561050357600080fd5b50610517610512366004613850565b610ef5565b60405161023b9190613914565b34801561053057600080fd5b5061025961103a565b34801561054557600080fd5b506105b661055436600461371f565b6040805160608082018352600080835260208084018290529284018190529384526005825292829020825193840183525462ffffff811684526301000000810460ff169184019190915264010000000090046001600160601b03169082015290565b60408051825162ffffff16815260208084015160ff1690820152918101516001600160601b03169082015260600161023b565b3480156105f557600080fd5b5061026b606481565b34801561060a57600080fd5b5061025961061936600461371f565b6110fe565b34801561062a57600080fd5b5061063e610639366004613976565b6111e5565b60405161023b9190613998565b34801561065757600080fd5b5061025961066636600461375d565b6112f7565b34801561067757600080fd5b5061022761068636600461377a565b611371565b34801561069757600080fd5b5061026b610bb881565b3480156106ad57600080fd5b506102276106bc36600461371f565b6001602052600090815260409020546001600160a01b031681565b3480156106e357600080fd5b5060408051614e208152606460208201520161023b565b34801561070657600080fd5b50600054610227906001600160a01b031681565b34801561072657600080fd5b5061025961073536600461371f565b6119c8565b34801561074657600080fd5b5061026b61075536600461371f565b6000908152600960205260409020546001600160c01b031690565b61026b61077e366004613c1c565b611cd1565b34801561078f57600080fd5b5061138861026b565b6000546040516227050b60e31b815261503160f01b60048201526001600160a01b0390911690630138285890602401602060405180830381865afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108089190613d50565b600160008181526020919091527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b815261544360f01b6004820152911690630138285890602401602060405180830381865afa158015610893573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108b79190613d50565b600080805260016020527fa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb4980546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b81526126a960f11b6004820152911690630138285890602401602060405180830381865afa15801561093f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109639190613d50565b60026000908152600160205260008051602061421983398151915280546001600160a01b039384166001600160a01b0319909116179055546040516227050b60e31b815261043560f41b6004820152911690630138285890602401602060405180830381865afa1580156109db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ff9190613d50565b600f60005260016020527f12bd632ff333b55931f9f8bda8b4ed27e86687f88c95871969d72474fb428c1480546001600160a01b0319166001600160a01b0392909216919091179055565b604080516001600160f81b03196020808301919091527f00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d60601b6bffffffffffffffffffffffff19166021830152603582018490527f1eb804b66941a2e8465fa0951be9c8b855b7794ee05b0789ab22a02ee1298ebe60558084019190915283518084039091018152607590920190925280519101206000905b92915050565b6002600052600160208190526000805160206142198339815191525460405163505ef22f60e01b815233600482015260248101929092526001600160a01b03169063505ef22f90604401602060405180830381865afa158015610b51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b759190613d78565b610b9a5760405162461bcd60e51b8152600401610b9190613d95565b60405180910390fd5b604051639d8168eb60e01b81526001600160a01b0382811660048301527f000000000000000000000000a5190b1bf3fc95d28b739fff3bcfc106acf3863e1690639d8168eb906024015b600060405180830381600087803b158015610bfe57600080fd5b505af1158015610c12573d6000803e3d6000fd5b5050505050565b60007f000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9d9190613ddb565b905090565b610cb56064670de0b6b3a7640000613e0a565b81565b60066020528260005260406000206020528160005260406000208181548110610ce057600080fd5b60009182526020909120015464ffffffffff811693506001600160601b03600160281b820481169350600160881b820416915062ffffff600160e81b9091041684565b606060086000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610de45760008481526020908190206040805160c081018252918501546001600160601b038116835263ffffffff600160601b8204811684860152600160801b8204811692840192909252600160a01b8104909116606083015262ffffff600160c01b820481166080840152600160d81b9091041660a0820152825260019092019101610d58565b505050509050919050565b610dfd8160008060006125a8565b50565b6002600052600160208190526000805160206142198339815191525460405163505ef22f60e01b815233600482015260248101929092526001600160a01b03169063505ef22f90604401602060405180830381865afa158015610e67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8b9190613d78565b610ea75760405162461bcd60e51b8152600401610b9190613d95565b604051639d8168eb60e01b81526001600160a01b0382811660048301527f000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd1690639d8168eb90602401610be4565b606081806001600160401b03811115610f1057610f106139a6565b604051908082528060200260200182016040528015610f4357816020015b6060815260200190600190039081610f2e5790505b50915060005b818110156110325760008030878785818110610f6757610f67613e2c565b9050602002810190610f799190613e42565b604051610f87929190613e8f565b600060405180830381855af49150503d8060008114610fc2576040519150601f19603f3d011682016040523d82523d6000602084013e610fc7565b606091505b509150915081610fff5780516000819003610ff85760405163f1a8c42d60e01b815260048101859052602401610b91565b8060208301fd5b8085848151811061101257611012613e2c565b60200260200101819052505050808061102a90613e9f565b915050610f49565b505092915050565b600080546040516227050b60e31b815261053560f41b60048201526001600160a01b0390911690630138285890602401602060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ab9190613d50565b6040516306394c9b60e01b81526001600160a01b0380831660048301529192507f00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d909116906306394c9b90602401610be4565b600061110d62093a8042613e0a565b90506000806111236301e1338062093a806126f1565b905060015b81811161117857600061113b8286613eb8565b6000878152600a602090815260408083208484529091529020549091506111629085613eb8565b935050808061117090613e9f565b915050611128565b50604051806040016040528061118d84612714565b6001600160c01b031681526020016111a48561277d565b6001600160401b0390811690915260009586526009602090815260409096208251929096015116600160c01b026001600160c01b0390911617909355505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152600083815260086020526040812080548490811061123757611237613e2c565b600091825260208083206040805160c08101825291909301546001600160601b03808216835263ffffffff600160601b8304811684860152600160801b8304811684870152600160a01b830416606084015262ffffff600160c01b830481166080850152600160d81b90920490911660a08301528885526005909252919092205481519193506401000000009004821691168111156112d75760006112e4565b81516112e4908290613ecb565b6001600160601b03168252509392505050565b6000546001600160a01b03161561134f576000546001600160a01b0316331461134f5760405162461bcd60e51b815260206004820152600a6024820152692737ba1036b0b9ba32b960b11b6044820152606401610b91565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b600080546040516323c5b10760e21b81523360048201526001600160a01b0390911690638f16c41c90602401602060405180830381865afa1580156113ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113de9190613d78565b6114355760405162461bcd60e51b815260206004820152602260248201527f43616c6c6572206973206e6f7420616e20696e7465726e616c20636f6e74726160448201526118dd60f21b6064820152608401610b91565b600084815260056020908152604080832080546301000000900460ff16845260099092528220909161146787876111e5565b60008881526006602090815260408083208a84529091528120855485549394509092630100000090910460ff1691600160c01b9091046001600160401b0316906114b462093a8042613e0a565b905060006114de866040015187602001516114cf9190613ef2565b63ffffffff1662093a806126f1565b905060006114ed8585856127e6565b90508282111561156a5760006115108c89600001516001600160601b0316612828565b905061151c8183613eb8565b915061152781612714565b6001600160c01b0316600a6000888152602001908152602001600020600085815260200190815260200160002060008282546115639190613f0f565b9091555050505b61157381612714565b8854899060009061158e9084906001600160c01b0316613f22565b92506101000a8154816001600160c01b0302191690836001600160c01b031602179055506115bb8361277d565b88546001600160401b0391909116600160c01b026001600160c01b03909116178855506115ee935089925061283e915050565b8454859060049061161190849064010000000090046001600160601b0316613f42565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060005b815481101561193057600082828154811061165557611655613e2c565b6000918252602080832060408051608081018252919093015464ffffffffff811682526001600160601b03600160281b82048116938301849052600160881b820481169483019490945262ffffff600160e81b9091041660608201528751909450909116906116c5908b90613f62565b6116cf9190613e0a565b905060008560a0015162ffffff16612710836116eb9190613f62565b6116f59190613e0a565b90506117008261283e565b85858154811061171257611712613e2c565b6000918252602090912001805460059061173d908490600160281b90046001600160601b0316613ecb565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555061179a86600001516001600160601b03168b85604001516001600160601b031661178b9190613f62565b6117959190613e0a565b61283e565b8585815481106117ac576117ac613e2c565b600091825260209091200180546011906117d7908490600160881b90046001600160601b0316613ecb565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555060006040518060a00160405280856060015162ffffff1681526020018a60000160009054906101000a900462ffffff1662ffffff168152602001886020015163ffffffff168152602001886040015163ffffffff168152602001848152509050600086868154811061186f5761186f613e2c565b60009182526020909120015464ffffffffff16905061188d81610a4a565b60408051632e28698360e01b815260048101869052845160248201526020850151604482015290840151606482015260608401516084820152608084015160a48201526001600160a01b039190911690632e2869839060c401600060405180830381600087803b15801561190057600080fd5b505af1158015611914573d6000803e3d6000fd5b505050505050505050808061192890613e9f565b915050611638565b506040516331a9108f60e11b8152600481018990527f000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd6001600160a01b031690636352211e90602401602060405180830381865afa158015611996573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ba9190613d50565b9450505050505b9392505050565b6000818152600860205260408120546119e390600190613f0f565b905060006119f183836111e5565b60008481526005602090815260408083208151606081018352905462ffffff811682526301000000810460ff168285015264010000000090046001600160601b031681830152908401519184015193945092611a4d9190613ef2565b63ffffffff16905042811115611a7957604051637f65db9f60e11b815260048101869052602401610b91565b60005b6000868152600660209081526040808320888452909152902054811015611bf75760008681526006602090815260408083208884529091528120805483908110611ac857611ac8613e2c565b600091825260209182902060408051608081018252929091015464ffffffffff81168352600160281b81046001600160601b0390811694840194909452600160881b810490931690820152600160e81b90910462ffffff1660608201529050611b2f6136b5565b845162ffffff90811682526060830151166040820152602086015163ffffffff1660c082015260e081018490528151611b6e9064ffffffffff16610a4a565b6001600160a01b031663a7d4d7e4600080846040518463ffffffff1660e01b8152600401611b9e93929190614005565b60408051808303816000875af1158015611bbc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611be09190614021565b505050508080611bef90613e9f565b915050611a7c565b506000611c0762093a8042613e0a565b90506000611c188362093a806126f1565b905080821015611cc857845160208086015160ff166000908152600a8252604080822085835290925290812080546001600160601b0390931692909190611c60908490613f0f565b9091555050845160208086015160ff16600090815260099091526040812080546001600160601b0390931692909190611ca39084906001600160c01b0316613f22565b92506101000a8154816001600160c01b0302191690836001600160c01b031602179055505b50505050505050565b6002600081815260016020526000805160206142198339815191525460405163505ef22f60e01b8152336004820152602481019390935290916001600160a01b039091169063505ef22f90604401602060405180830381865afa158015611d3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d609190613d78565b611da55760405162461bcd60e51b815260206004820152601660248201527521b0b63632b91034b9903737ba10309036b2b6b132b960511b6044820152606401610b91565b6002805403611df65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610b91565b6002805560005460408051600162f6c75960e01b0319815290516001600160a01b039092169163ff0938a7916004808201926020929091908290030181865afa158015611e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6b9190613d78565b15611eab5760405162461bcd60e51b815260206004820152601060248201526f14de5cdd195b481a5cc81c185d5cd95960821b6044820152606401610b91565b6224ea008360a0015163ffffffff161015611ed95760405163056d6c0b60e11b815260040160405180910390fd5b6301e133808360a0015163ffffffff161115611f085760405163a15784c760e01b815260040160405180910390fd5b610bb883610100015161ffff161115611f3457604051636bdaa48360e11b815260040160405180910390fd5b82608001516001600160601b0316600003611f6257604051636e36642760e11b815260040160405180910390fd5b826060015160ff168360e0015160ff1614158015611f88575060e083015160ff90811614155b15611fa6576040516304b4a0b760e51b815260040160405180910390fd5b6000611fb06136b5565b6000611fba6128a2565b9050856040015162ffffff16816001600160a01b0316634a348da96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612004573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120289190613ddb565b11612046576040516379de4af560e01b815260040160405180910390fd5b60408087015190516302db1c0360e61b815262ffffff909116600482015260009081906001600160a01b0384169063b6c700c09060240161012060405180830381865afa15801561209b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120bf91906140b4565b915091508160a00151156120e657604051631340cecb60e21b815260040160405180910390fd5b612101886060015160ff16836040015163ffffffff166128c9565b61211e57604051637548463d60e01b815260040160405180910390fd5b604088015162ffffff168452602080850187905260a0808a015163ffffffff9081166060880152929091015190911660808086019190915260c0830151151591850191909152614e20610120850152015161ffff16610140830152506113886101608201526064610180820152845160009081036122be5760208601516040516335313c2160e11b81526001600160a01b0391821660048201527f000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd90911690636a627842906024016020604051808303816000875af1158015612205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122299190613ddb565b60408051606080820183528983015162ffffff9081168352908a015160ff9081166020808501918252600085870181815288825260059092529590952093518454915195516001600160601b0316640100000000026fffffffffffffffffffffffff00000000199690931663010000000263ffffffff19909216931692909217919091179290921691909117905593506122d7565b60405163d0dca47b60e01b815260040160405180910390fd5b60006122e161297f565b6060880151604051631d76154960e31b815260ff90911660048201526001600160a01b03919091169063ebb0aa48906024016020604051808303816000875af1158015612332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123569190613ddb565b60208401869052905060008061236e8589858961298a565b9150915088608001516001600160601b03168210156123a0576040516304508f7760e41b815260040160405180910390fd5b600860008881526020019081526020016000206040518060c001604052806123c78561283e565b6001600160601b031681526020016123de42612ef8565b63ffffffff1681526020018b60a0015163ffffffff1681526020016124068860800151612ef8565b63ffffffff16815260200161241c611388612f5d565b62ffffff168152602001612431614e20612f5d565b62ffffff90811690915282546001810184556000938452602093849020835191018054948401516040850151606080870151608088015160a0988901518816600160d81b0262ffffff60d81b1991909816600160c01b021665ffffffffffff60c01b1963ffffffff928316600160a01b0263ffffffff60a01b19958416600160801b029590951667ffffffffffffffff60801b19968416600160601b026fffffffffffffffffffffffffffffffff19909c166001600160601b03909916989098179a909a17949094169590951791909117969096161792909217909155918b0151908b01516125299260ff90921691859116876125a8565b61254c818a60e0015160ff16858c60c001518d61010001518e6101200151612fc1565b85896040015162ffffff16887f3da7af757f7e475ca8192a0ff54890cc9d744e04ecd45be53e8bfee6c93d2de2338d610140015160405161258e929190614171565b60405180910390a450506001600255509295945050505050565b60008481526009602090815260408083208151808301909252546001600160c01b0381168252600160c01b90046001600160401b031691810191909152906125f362093a8042613e0a565b82519091506001600160c01b0316801561262c5761261f8784602001516001600160401b0316846127e6565b6126299082613f0f565b90505b6126368482613f0f565b90506126428682613eb8565b905061264d8261277d565b6001600160401b0316602084015261266481612714565b6001600160c01b039081168452600088815260096020908152604082208651918701516001600160401b0316600160c01b0291909316179091556126b46126ab8742613eb8565b62093a806126f1565b6000898152600a602090815260408083208484529091528120805492935089929091906126e2908490613eb8565b90915550505050505050505050565b60008160016127008286613eb8565b61270a9190613f0f565b6119c19190613e0a565b6000600160c01b82106127795760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663932206269747360c81b6064820152608401610b91565b5090565b60006801000000000000000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608401610b91565b60005b818310156119c1576127fa83613e9f565b6000858152600a602090815260408083208484529091529020549093506128219082613eb8565b90506127e9565b600081831061283757816119c1565b5090919050565b6000600160601b82106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201526536206269747360d01b6064820152608401610b91565b6000600181600f5b81526020810191909152604001600020546001600160a01b0316919050565b600081158015906128dd57506001831b8216155b156128ea57506000610ae4565b60006128f461297f565b6001600160a01b031663eac8f5b8856040518263ffffffff1660e01b815260040161292191815260200190565b606060405180830381865afa15801561293e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129629190614195565b90508060200151801561297757508060400151155b949350505050565b6000600181816128aa565b600080600060405180608001604052806000815260200160008152602001600081526020016000815250905060008085116129c65760006129f8565b6020808901516000908152600690915260408120906129e6600188613f0f565b81526020810191909152604001600020545b825260005b8751811015612ecd578251811015612c49576020808a0151600090815260069091526040812081612a2f60018a613f0f565b81526020019081526020016000208281548110612a4e57612a4e613e2c565b600091825260209182902060408051608081018252929091015464ffffffffff81168352600160281b81046001600160601b0390811694840194909452600160881b810490931690820152600160e81b90910462ffffff1660608201528951909150899083908110612ac257612ac2613e2c565b60200260200101516000015164ffffffffff16816000015164ffffffffff1614612aff5760405163034007f360e31b815260040160405180910390fd5b888281518110612b1157612b11613e2c565b60200260200101516020015115612bd3576020808b015160009081526006825260408082208a835283528082208054600181018255908352918390208451920180549385015191850151606086015162ffffff16600160e81b026001600160e81b036001600160601b03928316600160881b02166001600160881b0392909416600160281b81026001600160881b031990971664ffffffffff9096169590951795909517169190911792909217909155612bcb9084613eb8565b925050612ebb565b60408101516001600160601b0316602085015260c08a015160e08b0151612bfa9190613f0f565b428b60e00151612c0a9190613f0f565b82604001516001600160601b0316612c229190613f62565b612c2c9190613e0a565b60408086019190915260609091015162ffffff16908a0152612c51565b600060408a01525b6000612ca8612c90670de0b6b3a76400008b8581518110612c7457612c74613e2c565b602002602001015160400151612c8a9190613f62565b8a6126f1565b612ca36064670de0b6b3a7640000613e0a565b613448565b9050600080612cda8b8581518110612cc257612cc2613e2c565b60200260200101516000015164ffffffffff16610a4a565b6001600160a01b031663a7d4d7e48488602001518f6040518463ffffffff1660e01b8152600401612d0d93929190614005565b60408051808303816000875af1158015612d2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d4f9190614021565b9150915082600014612e7c57600660008d60200151815260200190815260200160002060008a815260200190815260200160002060405180608001604052808d8781518110612da057612da0613e2c565b60200260200101516000015164ffffffffff168152602001612dc18661283e565b6001600160601b03168152602001612dd88561283e565b6001600160601b03168152602001612def84612f5d565b62ffffff90811690915282546001810184556000938452602093849020835191018054948401516040850151606090950151909316600160e81b026001600160e81b036001600160601b03958616600160881b02166001600160881b0395909416600160281b026001600160881b031990961664ffffffffff909316929092179490941792909216171790555b8186604001511015612e9c576040860151612e979083613f0f565b612e9f565b60005b612ea99088613eb8565b9650612eb58386613eb8565b94505050505b80612ec581613e9f565b9150506129fd565b50670de0b6b3a7640000612ee18783613f62565b612eeb9190613e0a565b9350505094509492505050565b600064010000000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608401610b91565b6000630100000082106127795760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201526534206269747360d01b6064820152608401610b91565b8415801590612fd05750600034115b15612fee57604051630f33611760e01b815260040160405180910390fd5b60fe19850161316857600061ffff831615613037578661301461ffff8516612710613f0f565b6130206127108a613f62565b61302a9190613e0a565b6130349190613f0f565b90505b836130428289613eb8565b11156130615760405163265dbe6d60e11b815260040160405180910390fd5b600061306b61345f565b60405163079cc67960e41b8152336004820152602481018a90529091506001600160a01b038216906379cc6790906044016020604051808303816000875af11580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190613d78565b50811561316157604051630d1af10360e01b81523360048201526001600160a01b03848116602483015260448201849052821690630d1af103906064016020604051808303816000875af115801561313b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061315f9190613d78565b505b5050613440565b600061317261297f565b90506000670de0b6b3a76400006131898988613f62565b6131939190613e0a565b90506000816131a861ffff8716612710613f0f565b6131b461271085613f62565b6131be9190613e0a565b6131c89190613f0f565b905060006131d68284613eb8565b9050868111156131f95760405163265dbe6d60e11b815260040160405180910390fd5b88613399578034101561321f5760405163f244866f60e01b815260040160405180910390fd5b600061322b8234613f0f565b90506000856001600160a01b03168560405160006040518083038185875af1925050503d806000811461327a576040519150601f19603f3d011682016040523d82523d6000602084013e61327f565b606091505b50509050806132a15760405163ab1ee9bf60e01b815260040160405180910390fd5b50821561331e576000866001600160a01b03168460405160006040518083038185875af1925050503d80600081146132f5576040519150601f19603f3d011682016040523d82523d6000602084013e6132fa565b606091505b505090508061331c576040516308118ce960e21b815260040160405180910390fd5b505b801561338f57604051600090339083908381818185875af1925050503d8060008114613366576040519150601f19603f3d011682016040523d82523d6000602084013e61336b565b606091505b505090508061338d576040516366abea6d60e11b815260040160405180910390fd5b505b5050505050613440565b604051631d591eb760e31b8152600481018a90526000906001600160a01b0386169063eac8f5b890602401606060405180830381865afa1580156133e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134059190614195565b5190508061341e6001600160a01b03821633888861346a565b8315613439576134396001600160a01b03821633898761346a565b5050505050505b505050505050565b60008161345584846126f1565b6119c19190613f62565b6000600181806128aa565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526134c49085906134ca565b50505050565b600061351f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135a19092919063ffffffff16565b80519091501561359c578080602001905181019061353d9190613d78565b61359c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b91565b505050565b60606129778484600085856001600160a01b0385163b6136035760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b91565b600080866001600160a01b0316858760405161361f91906141e9565b60006040518083038185875af1925050503d806000811461365c576040519150601f19603f3d011682016040523d82523d6000602084013e613661565b606091505b509150915061367182828661367c565b979650505050505050565b6060831561368b5750816119c1565b82511561369b5782518084602001fd5b8160405162461bcd60e51b8152600401610b919190614205565b604051806101a001604052806000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561373157600080fd5b5035919050565b6001600160a01b0381168114610dfd57600080fd5b803561375881613738565b919050565b60006020828403121561376f57600080fd5b81356119c181613738565b60008060006060848603121561378f57600080fd5b505081359360208301359350604090920135919050565b6001600160601b038151168252602081015163ffffffff80821660208501528060408401511660408501528060608401511660608501525050608081015162ffffff80821660808501528060a08401511660a085015250505050565b6020808252825182820181905260009190848201906040850190845b81811015613844576138318385516137a6565b9284019260c0929092019160010161381e565b50909695505050505050565b6000806020838503121561386357600080fd5b82356001600160401b038082111561387a57600080fd5b818501915085601f83011261388e57600080fd5b81358181111561389d57600080fd5b8660208260051b85010111156138b257600080fd5b60209290920196919550909350505050565b60005b838110156138df5781810151838201526020016138c7565b50506000910152565b600081518084526139008160208601602086016138c4565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561396957603f198886030184526139578583516138e8565b9450928501929085019060010161393b565b5092979650505050505050565b6000806040838503121561398957600080fd5b50508035926020909101359150565b60c08101610ae482846137a6565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156139de576139de6139a6565b60405290565b60405161016081016001600160401b03811182821017156139de576139de6139a6565b60405160e081016001600160401b03811182821017156139de576139de6139a6565b604051601f8201601f191681016001600160401b0381118282101715613a5157613a516139a6565b604052919050565b803562ffffff8116811461375857600080fd5b60ff81168114610dfd57600080fd5b803561375881613a6c565b80356001600160601b038116811461375857600080fd5b63ffffffff81168114610dfd57600080fd5b803561375881613a9d565b61ffff81168114610dfd57600080fd5b803561375881613aba565b600082601f830112613ae657600080fd5b81356001600160401b03811115613aff57613aff6139a6565b613b12601f8201601f1916602001613a29565b818152846020838601011115613b2757600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610dfd57600080fd5b600082601f830112613b6357600080fd5b813560206001600160401b03821115613b7e57613b7e6139a6565b613b8c818360051b01613a29565b82815260609283028501820192828201919087851115613bab57600080fd5b8387015b85811015613c0f5781818a031215613bc75760008081fd5b613bcf6139bc565b813564ffffffffff81168114613be55760008081fd5b815281860135613bf481613b44565b81870152604082810135908201528452928401928101613baf565b5090979650505050505050565b60008060408385031215613c2f57600080fd5b82356001600160401b0380821115613c4657600080fd5b908401906101608287031215613c5b57600080fd5b613c636139e4565b82358152613c736020840161374d565b6020820152613c8460408401613a59565b6040820152613c9560608401613a7b565b6060820152613ca660808401613a86565b6080820152613cb760a08401613aaf565b60a082015260c083013560c0820152613cd260e08401613a7b565b60e0820152610100613ce5818501613aca565b90820152610120613cf784820161374d565b908201526101408381013583811115613d0f57600080fd5b613d1b89828701613ad5565b828401525050809450506020850135915080821115613d3957600080fd5b50613d4685828601613b52565b9150509250929050565b600060208284031215613d6257600080fd5b81516119c181613738565b805161375881613b44565b600060208284031215613d8a57600080fd5b81516119c181613b44565b60208082526026908201527f43616c6c6572206973206e6f7420616e2061647669736f727920626f6172642060408201526536b2b6b132b960d11b606082015260800190565b600060208284031215613ded57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082613e2757634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b6000808335601e19843603018112613e5957600080fd5b8301803591506001600160401b03821115613e7357600080fd5b602001915036819003821315613e8857600080fd5b9250929050565b8183823760009101908152919050565b600060018201613eb157613eb1613df4565b5060010190565b80820180821115610ae457610ae4613df4565b6001600160601b03828116828216039080821115613eeb57613eeb613df4565b5092915050565b63ffffffff818116838216019080821115613eeb57613eeb613df4565b81810381811115610ae457610ae4613df4565b6001600160c01b03828116828216039080821115613eeb57613eeb613df4565b6001600160601b03818116838216019080821115613eeb57613eeb613df4565b8082028115828204841417610ae457610ae4613df4565b805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a0810151613fb860a084018215159052565b5060c0818101519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018090810151910152565b838152602081018390526101e081016129776040830184613f79565b6000806040838503121561403457600080fd5b505080516020909101519092909150565b805161375881613aba565b60006040828403121561406257600080fd5b604051604081018181106001600160401b0382111715614084576140846139a6565b8060405250809150825161409781613a6c565b815260208301516140a781613a9d565b6020919091015292915050565b6000808284036101208112156140c957600080fd5b60e08112156140d757600080fd5b506140e0613a07565b83516140eb81613aba565b815260208401516140fb81613738565b6020820152604084015161410e81613a9d565b6040820152606084015161412181613aba565b606082015261413260808501614045565b608082015261414360a08501613d6d565b60a082015261415460c08501613d6d565b60c082015291506141688460e08501614050565b90509250929050565b6001600160a01b0383168152604060208201819052600090612977908301846138e8565b6000606082840312156141a757600080fd5b6141af6139bc565b82516141ba81613738565b815260208301516141ca81613b44565b602082015260408301516141dd81613b44565b60408201529392505050565b600082516141fb8184602087016138c4565b9190910192915050565b6020815260006119c160208301846138e856fed9d16d34ffb15ba3a3d852f0d403e2ce1d691fb54de27ac87cd2f993f3ec330fa26469706673582212203061d10ea7b7902abc337bf0b5cf59d0f9caa941158abe95068613129c1f326d64736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd000000000000000000000000a5190b1bf3fc95d28b739fff3bcfc106acf3863e00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d0000000000000000000000009a16908588d42f1a223ac903abd383423d154107
-----Decoded View---------------
Arg [0] : _coverNFT (address): 0x986b56C78cb533bc89e00dE6Eb160d6ca2159bbd
Arg [1] : _stakingNFT (address): 0xA5190B1bf3fc95d28B739fFF3bcfc106aCF3863E
Arg [2] : _stakingPoolFactory (address): 0x28556B2C28CB6991A306093E67d1959905a8D28D
Arg [3] : _stakingPoolImplementation (address): 0x9a16908588d42f1a223Ac903aBd383423d154107
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000986b56c78cb533bc89e00de6eb160d6ca2159bbd
Arg [1] : 000000000000000000000000a5190b1bf3fc95d28b739fff3bcfc106acf3863e
Arg [2] : 00000000000000000000000028556b2c28cb6991a306093e67d1959905a8d28d
Arg [3] : 0000000000000000000000009a16908588d42f1a223ac903abd383423d154107
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.