Source Code
Overview
ETH Balance
0.3901056888888876 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 131 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Mint And Buy Sha... | 14499896 | 582 days ago | IN | 0.005500050111111 ETH | 0.000000296201 | ||||
| Buy Share | 14497811 | 582 days ago | IN | 0.005500050111111 ETH | 0.000000251687 | ||||
| Buy Share | 14401411 | 584 days ago | IN | 0.005504058999999 ETH | 0.000113272113 | ||||
| Buy Share | 14401375 | 584 days ago | IN | 0.005503207111111 ETH | 0.000113368653 | ||||
| Buy Share | 14401316 | 584 days ago | IN | 0.005500450999999 ETH | 0.000000635529 | ||||
| Sell Share | 14401289 | 584 days ago | IN | 0 ETH | 0.000000710288 | ||||
| Buy Share | 14401278 | 584 days ago | IN | 0.005500450999999 ETH | 0.000000740165 | ||||
| Buy Share | 14400718 | 584 days ago | IN | 0.005500200444444 ETH | 0.000001053887 | ||||
| Buy Share | 14400700 | 584 days ago | IN | 0.005500050111111 ETH | 0.000001111856 | ||||
| Buy Share | 14399337 | 584 days ago | IN | 0.005502455444444 ETH | 0.000000504087 | ||||
| Buy Share | 14399322 | 584 days ago | IN | 0.00551448211111 ETH | 0.000000509832 | ||||
| Sell Share | 14398307 | 584 days ago | IN | 0 ETH | 0.00000029764 | ||||
| Mint And Buy Sha... | 14398283 | 584 days ago | IN | 0.038507015555555 ETH | 0.000000381344 | ||||
| Buy Share | 14398133 | 584 days ago | IN | 0.005500200444444 ETH | 0.000000346126 | ||||
| Buy Share | 14398112 | 584 days ago | IN | 0.011000651444444 ETH | 0.000000355745 | ||||
| Buy Share | 14398040 | 584 days ago | IN | 0.05507040611111 ETH | 0.000011575492 | ||||
| Buy Share | 14398033 | 584 days ago | IN | 0.005502455444444 ETH | 0.000000401789 | ||||
| Buy Share | 14398013 | 584 days ago | IN | 0.027504509999999 ETH | 0.00001159093 | ||||
| Mint And Buy Sha... | 14397850 | 584 days ago | IN | 0.005500050111111 ETH | 0.000017971996 | ||||
| Buy Share | 14397536 | 584 days ago | IN | 0.005500450999999 ETH | 0.000013970943 | ||||
| Buy Share | 14396158 | 584 days ago | IN | 0.005500050111111 ETH | 0.000000453184 | ||||
| Buy Share | 14396116 | 584 days ago | IN | 0.005500200444444 ETH | 0.000000390066 | ||||
| Mint And Buy Sha... | 14391483 | 584 days ago | IN | 0.005500050111111 ETH | 0.000000279163 | ||||
| Buy Share | 14391442 | 584 days ago | IN | 0.005501803999999 ETH | 0.000000204067 | ||||
| Mint And Buy Sha... | 14370349 | 585 days ago | IN | 0.005500050111111 ETH | 0.000002338334 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | Amount | ||
|---|---|---|---|---|---|---|
| 14499896 | 582 days ago | 0.000250002277777 ETH | ||||
| 14499896 | 582 days ago | 0.000250002277777 ETH | ||||
| 14499896 | 582 days ago | 0.005000045555555 ETH | ||||
| 14499896 | 582 days ago | 0.005000045555555 ETH | ||||
| 14497811 | 582 days ago | 0.000250002277777 ETH | ||||
| 14497811 | 582 days ago | 0.000250002277777 ETH | ||||
| 14497811 | 582 days ago | 0.005000045555555 ETH | ||||
| 14497811 | 582 days ago | 0.005000045555555 ETH | ||||
| 14401411 | 584 days ago | 0.000250184499999 ETH | ||||
| 14401411 | 584 days ago | 0.000250184499999 ETH | ||||
| 14401411 | 584 days ago | 0.005003689999999 ETH | ||||
| 14401411 | 584 days ago | 0.005003689999999 ETH | ||||
| 14401375 | 584 days ago | 0.000250145777777 ETH | ||||
| 14401375 | 584 days ago | 0.000250145777777 ETH | ||||
| 14401375 | 584 days ago | 0.005002915555555 ETH | ||||
| 14401375 | 584 days ago | 0.005002915555555 ETH | ||||
| 14401316 | 584 days ago | 0.000250020499999 ETH | ||||
| 14401316 | 584 days ago | 0.000250020499999 ETH | ||||
| 14401316 | 584 days ago | 0.005000409999999 ETH | ||||
| 14401316 | 584 days ago | 0.005000409999999 ETH | ||||
| 14401289 | 584 days ago | 0.000250020499999 ETH | ||||
| 14401289 | 584 days ago | 0.000250020499999 ETH | ||||
| 14401289 | 584 days ago | 0.004500368999999 ETH | ||||
| 14401278 | 584 days ago | 0.000250020499999 ETH | ||||
| 14401278 | 584 days ago | 0.000250020499999 ETH |
Loading...
Loading
Contract Name:
SharesFactoryV1
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import "@openzeppelin/contracts/access/Ownable2Step.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IShare } from "../interface/IShare.sol";
import { IYieldAggregator } from "contracts/interface/IYieldAggregator.sol";
import { BondingCurveLib } from "../lib/BondingCurveLib.sol";
contract SharesFactoryV1 is Ownable2Step, ReentrancyGuard {
using SafeERC20 for IERC20;
struct Curve {
uint96 basePrice;
uint128 linearPriceSlope;
uint32 inflectionPoint;
uint128 inflectionPrice;
bool exists;
}
struct Share {
address creator;
uint8 curveType;
}
mapping(uint256 shareId => Share share) public sharesMap;
mapping(uint8 curveType => Curve curve) public curvesMap;
address public immutable ERC1155;
uint256 public constant TIMELOCK_DURATION = 3 days;
uint256 public shareIndex;
uint256 public depositedETHAmount;
uint256 public referralFeePercent = 5 * 1e16;
uint256 public creatorFeePercent = 5 * 1e16;
uint256 public migrationDeadline;
IYieldAggregator public yieldAggregator;
address public pendingAggregator;
address public blankAggregator;
event QueueMigrateYield(address indexed newAggregator, uint256 deadline);
event MigrateYield(address indexed newAggregator, uint256 timestamp);
event ClaimYield(uint256 amount, address indexed to);
event SetCurve(uint8 indexed curveType);
event SetFee(uint256 indexed feePercent, string feeType);
event Mint(uint256 indexed id, address indexed creator, uint8 indexed curveType);
event Buy(uint256 indexed id, address indexed buyer, uint32 quantity, uint256 totalPrice);
event Sell(uint256 indexed id, address indexed seller, uint32 quantity, uint256 totalPrice);
constructor(
address _ERC1155,
uint96 _basePrice,
uint32 _inflectionPoint,
uint128 _inflectionPrice,
uint128 _linearPriceSlope
) {
// Set ERC1155 address
ERC1155 = _ERC1155;
// Set default curve params
curvesMap[0] = Curve({
basePrice: _basePrice, // 5000000000000000;
inflectionPoint: _inflectionPoint, // 1500;
inflectionPrice: _inflectionPrice, // 102500000000000000;
linearPriceSlope: _linearPriceSlope, // 0;
exists: true
});
}
fallback() external payable { }
receive() external payable { }
function getShare(uint256 shareId) public view returns (address creator, uint8 curveType) {
require(shareId < shareIndex, "Invalid shareId");
Share memory share = sharesMap[shareId];
return (share.creator, share.curveType);
}
function getCurve(uint8 curveType) public view returns (uint96, uint32, uint128, uint128, bool) {
require(curvesMap[curveType].exists, "Invalid curveType");
Curve memory curve = curvesMap[curveType];
uint96 basePrice = curve.basePrice;
uint32 g = curve.inflectionPoint;
uint128 h = curve.inflectionPrice;
uint128 m = curve.linearPriceSlope;
bool exists = curve.exists;
return (basePrice, g, h, m, exists);
}
function getSubTotal(uint32 fromSupply, uint32 quantity, uint8 curveType) public view returns (uint256) {
(uint96 basePrice, uint32 g, uint128 h, uint128 m,) = getCurve(curveType);
return _subTotal(fromSupply, quantity, basePrice, g, h, m);
}
function setReferralFeePercent(uint256 _feePercent) external onlyOwner {
referralFeePercent = _feePercent;
emit SetFee(_feePercent, "referral");
}
function setCreatorFeePercent(uint256 _feePercent) external onlyOwner {
creatorFeePercent = _feePercent;
emit SetFee(_feePercent, "creator");
}
function setCurveType(
uint8 _curveType,
uint96 _basePrice,
uint32 _inflectionPoint,
uint128 _inflectionPrice,
uint128 _linearPriceSlope
) external onlyOwner {
require(!curvesMap[_curveType].exists, "Curve already initialized");
Curve memory newCurve = Curve({
basePrice: _basePrice,
inflectionPoint: _inflectionPoint,
inflectionPrice: _inflectionPrice,
linearPriceSlope: _linearPriceSlope,
exists: true
});
curvesMap[_curveType] = newCurve;
emit SetCurve(_curveType);
}
/**
* @notice Reset yieldAggregator, always fallback to blankAggregator.
* Case 1: address(0) -> yieldAggregator, make the blankAggregator as default yieldAggregator.
* Case 2: yieldAggregator -> blankAggregator, which cancels yield farming.
*/
function resetYield(address _yieldAggregator) external onlyOwner {
require(_yieldAggregator != address(0), "Invalid yieldAggregator");
if (address(yieldAggregator) == address(0)) {
blankAggregator = _yieldAggregator;
_setYieldAggregator(_yieldAggregator);
} else {
_migrate(blankAggregator);
}
}
/**
* @notice Ask to migrate a new yield aggregator with timelock.
* @param _yieldAggregator The address of the yield aggregator.
*/
function queueMigrateYield(address _yieldAggregator) external onlyOwner {
require(_yieldAggregator != address(0), "Invalid yieldAggregator");
pendingAggregator = _yieldAggregator;
migrationDeadline = block.timestamp + TIMELOCK_DURATION;
emit QueueMigrateYield(_yieldAggregator, migrationDeadline);
}
/**
* @notice Migrate a new yield aggregator after timelock.
*/
function executeMigrateYield() external onlyOwner {
require(pendingAggregator != address(0), "Invalid pendingAggregator");
require(block.timestamp >= migrationDeadline, "Timelock not expired");
_migrate(pendingAggregator);
delete pendingAggregator; // Reset pending aggregator
delete migrationDeadline; // Reset migration deadline
}
/**
* @notice Only for owner to claim a specific yield amount.
* @param amount The yield amount the owner claims.
* @param to The address will be a smart contract to distribute yield to creators.
*/
function claimYield(uint256 amount, address to) public onlyOwner {
uint256 maxAmount = yieldAggregator.yieldMaxClaimable(depositedETHAmount);
require(amount <= maxAmount, "Insufficient yield");
yieldAggregator.yieldWithdraw(amount);
_safeTransferETH(to, amount);
emit ClaimYield(amount, to);
}
/**
* @notice Mint a share and buy it in one transaction.
* @param curveType The type of the curve.
* @param quantity The quantity of shares.
* @param referral The address of the referral fee recipient.
*/
function mintAndBuyShare(uint8 curveType, uint32 quantity, address referral) public payable {
mintShare(curveType);
buyShare(shareIndex - 1, quantity, referral);
}
/**
* @notice Mint a share with an auto-incremented ID.
* @dev The share ID is identical to the ERC1155 ID.
*/
function mintShare(uint8 curveType) public {
require(curvesMap[curveType].exists, "Invalid curveType");
Share memory newShare = Share({ creator: msg.sender, curveType: curveType });
sharesMap[shareIndex] = newShare;
emit Mint(shareIndex, msg.sender, curveType);
shareIndex++;
}
/**
* @param shareId The ID of the share.
* @param quantity The quantity of shares.
* @param referral The address of the referral fee recipient.
*/
function buyShare(uint256 shareId, uint32 quantity, address referral) public payable nonReentrant {
require(address(yieldAggregator) != address(0), "Invalid yieldAggregator");
require(shareId < shareIndex, "Invalid shareId");
(
uint256 buyPriceAfterFee,
uint256 buyPrice,
uint256 referralFee,
uint256 creatorFee
) = getBuyPriceAfterFee(shareId, quantity, referral);
require(msg.value >= buyPriceAfterFee, "Insufficient payment");
// Mint shares to the buyer
IShare(ERC1155).shareMint(msg.sender, shareId, quantity);
emit Buy(shareId, msg.sender, quantity, buyPriceAfterFee);
// Deposit the buy price (in ETH) to the yield aggregator (e.g., Aave)
_safeTransferETH(address(yieldAggregator), buyPrice);
yieldAggregator.yieldDeposit();
depositedETHAmount += buyPrice;
// Transfer referral and creator fees
(address creator,) = getShare(shareId);
_safeTransferETH(creator, creatorFee);
_safeTransferETH(referral, referralFee);
// If buyer paid more than necessary, refund the excess
uint256 refundAmount = msg.value - buyPriceAfterFee;
if (refundAmount > 0) {
_safeTransferETH(msg.sender, refundAmount);
}
}
/**
* @param shareId The ID of the share.
* @param quantity The quantity of shares.
* @param minETHAmount The minimum amount of ETH will be used for slippage protection.
* @param referral The address of the referral fee recipient.
*/
function sellShare(
uint256 shareId,
uint32 quantity,
uint256 minETHAmount,
address referral
) public nonReentrant {
require(shareId < shareIndex, "Invalid shareId");
require(
IShare(ERC1155).shareBalanceOf(msg.sender, shareId) >= quantity,
"Insufficient shares"
);
(
uint256 sellPriceAfterFee,
uint256 sellPrice,
uint256 referralFee,
uint256 creatorFee
) = getSellPriceAfterFee(shareId, quantity, referral);
require(sellPriceAfterFee >= minETHAmount, "Insufficient minReceive");
// Burn shares from the seller
IShare(ERC1155).shareBurn(msg.sender, shareId, quantity);
emit Sell(shareId, msg.sender, quantity, sellPriceAfterFee);
// Withdraw the sell price (in ETH) from the yield aggregator (e.g. Aave)
yieldAggregator.yieldWithdraw(sellPrice);
depositedETHAmount -= sellPrice;
// Transfer ETH to the seller
_safeTransferETH(msg.sender, sellPriceAfterFee);
// Transfer referral and creator fees
(address creator,) = getShare(shareId);
_safeTransferETH(creator, creatorFee);
_safeTransferETH(referral, referralFee);
}
/**
* @notice Calculates buy price and fees.
* @return buyPriceAfterFee The amount user pay after fees.
* @return buyPrice The initial price of the shares.
* @return referralFee Fee by the referral. If = address(0), there is no referral fee.
* @return creatorFee Fee by the share's creator.
*/
function getBuyPriceAfterFee(
uint256 shareId,
uint32 quantity,
address referral
)
public
view
returns (
uint256 buyPriceAfterFee,
uint256 buyPrice,
uint256 referralFee,
uint256 creatorFee
)
{
(, uint8 curveType) = getShare(shareId);
uint256 fromSupply = IShare(ERC1155).shareFromSupply(shareId);
uint256 actualReferralFeePercent = referral != address(0) ? referralFeePercent : 0;
buyPrice = getSubTotal(uint32(fromSupply), quantity, curveType);
referralFee = (buyPrice * actualReferralFeePercent) / 1 ether;
creatorFee = (buyPrice * creatorFeePercent) / 1 ether;
buyPriceAfterFee = buyPrice + referralFee + creatorFee;
}
/**
* @notice Calculates sell price and fees.
* @return sellPriceAfterFee The amount user receives after fees.
* @return sellPrice The initial price of the shares.
* @return referralFee Fee by the referral. If = address(0), there is no referral fee.
* @return creatorFee Fee by the share's creator.
*/
function getSellPriceAfterFee(
uint256 shareId,
uint32 quantity,
address referral
)
public
view
returns (
uint256 sellPriceAfterFee,
uint256 sellPrice,
uint256 referralFee,
uint256 creatorFee
)
{
(, uint8 curveType) = getShare(shareId);
uint256 fromSupply = IShare(ERC1155).shareFromSupply(shareId);
uint256 actualReferralFeePercent = referral != address(0) ? referralFeePercent : 0;
require(fromSupply >= quantity, "Exceeds supply");
sellPrice = getSubTotal(uint32(fromSupply) - quantity, quantity, curveType);
referralFee = (sellPrice * actualReferralFeePercent) / 1 ether;
creatorFee = (sellPrice * creatorFeePercent) / 1 ether;
sellPriceAfterFee = sellPrice - referralFee - creatorFee;
}
/**
* @notice Sets the yieldAggregator and approves it to spend the yieldToken.
* @param _yieldAggregator The address of the yieldAggregator.
*/
function _setYieldAggregator(address _yieldAggregator) internal {
yieldAggregator = IYieldAggregator(_yieldAggregator);
address yieldToken = yieldAggregator.yieldToken();
IERC20(yieldToken).safeApprove(_yieldAggregator, type(uint256).max);
}
/**
* @notice Migrate yield aggregator
* @param _yieldAggregator The address of the yieldAggregator
*/
function _migrate(address _yieldAggregator) internal {
// Step 1: Withdraw all yieldToken into ETH.
_withdrawAllYieldTokenToETH();
// Step 2: Revoke the approval of the old yieldAggregator.
address yieldToken = yieldAggregator.yieldToken();
IERC20(yieldToken).safeApprove(address(yieldAggregator), 0);
// Step 3: Set the new yieldAggregator.
_setYieldAggregator(_yieldAggregator);
// Step 4: Deposit all ETH into the new yieldAggregator as yieldToken.
_depositAllETHToYieldToken();
emit MigrateYield(address(_yieldAggregator), block.timestamp);
}
/**
* @notice Withdraws all yieldToken into the SharesFactory as ETH.
*/
function _withdrawAllYieldTokenToETH() internal {
uint256 withdrawableETHAmount = yieldAggregator.yieldBalanceOf(address(this));
yieldAggregator.yieldWithdraw(withdrawableETHAmount);
}
/**
* @notice Deposits all ETH into the yieldAggregator as yieldToken.
*/
function _depositAllETHToYieldToken() internal {
uint256 ethAmount = address(this).balance;
_safeTransferETH(address(yieldAggregator), ethAmount);
yieldAggregator.yieldDeposit();
}
/**
* @dev Returns the area under the bonding curve, which is the price before any fees.
* @param fromSupply The starting share supply.
* @param quantity The number of shares to be minted.
* @return subTotal The area under the bonding curve.
*/
function _subTotal(
uint32 fromSupply,
uint32 quantity,
uint96 basePrice,
uint32 inflectionPoint,
uint128 inflectionPrice,
uint128 linearPriceSlope
) public pure returns (uint256 subTotal) {
unchecked {
subTotal = basePrice * quantity;
subTotal += BondingCurveLib.linearSum(linearPriceSlope, fromSupply, quantity);
subTotal += BondingCurveLib.sigmoid2Sum(inflectionPoint, inflectionPrice, fromSupply, quantity);
}
}
/**
* @notice Transfers ETH to the recipient address
* @param to The destination of the transfer
* @param value The value to be transferred
* @dev Fails with `ETH transfer failed`
*/
function _safeTransferETH(address to, uint256 value) internal {
if (value > 0) {
(bool success,) = to.call{ value: value }(new bytes(0));
require(success, "ETH transfer failed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.0;
import "./Ownable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2Step is Ownable {
address private _pendingOwner;
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
return _pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
_pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
delete _pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner");
_transferOwnership(sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (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() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/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;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
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));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
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");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
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");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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
pragma solidity 0.8.25;
interface IShare {
function shareMint(address to, uint256 id, uint256 amount) external;
function shareBurn(address from, uint256 id, uint256 amount) external;
function shareFromSupply(uint256 id) external view returns (uint256);
function shareBalanceOf(address user, uint256 id) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
interface IYieldAggregator {
function yieldDeposit() external;
function yieldWithdraw(uint256 amount) external;
function yieldBalanceOf(address owner) external view returns (uint256 withdrawableETHAmount);
function yieldToken() external view returns (address);
function yieldMaxClaimable(uint256 depositedETHAmount) external view returns (uint256 maxClaimableETH);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol";
library BondingCurveLib {
function sigmoid2Sum(
uint32 inflectionPoint,
uint128 inflectionPrice,
uint32 fromSupply,
uint32 quantity
) internal pure returns (uint256 sum) {
// We don't need checked arithmetic for the sum.
// The max possible sum for the quadratic region is capped at:
// `n * (n + 1) * (2*n + 1) * h < 2**32 * 2**33 * 2**34 * 2**128 = 2**227`.
// The max possible sum for the sqrt region is capped at:
// `end * (2*h * sqrt(end)) < 2**32 * 2**129 * 2**16 = 2**177`.
// The overall sum is capped by:
// `2**161 + 2**227 <= 2**228 < 2 **256`.
// The result will be small enough for unchecked multiplication with a 16-bit BPS.
unchecked {
uint256 g = inflectionPoint;
uint256 h = inflectionPrice;
// Early return to save gas if either `g` or `h` is zero.
if (g * h == 0) {
return 0;
}
uint256 s = uint256(fromSupply) + 1;
uint256 end = s + uint256(quantity);
uint256 quadraticEnd = FixedPointMathLib.min(g, end);
if (s < quadraticEnd) {
uint256 k = uint256(fromSupply); // `s - 1`.
uint256 n = quadraticEnd - 1;
// In practice, `h` (units: wei) will be set to be much greater than `g * g`.
uint256 a = FixedPointMathLib.rawDiv(h, g * g);
// Use the closed form to compute the sum.
// sum(i ^2)/ g^2 considered as infinitesimal and use taylor series
sum = ((n * (n + 1) * ((n << 1) + 1) - k * (k + 1) * ((k << 1) + 1)) / 6) * a;
s = quadraticEnd;
}
if (s < end) {
uint256 c = (3 * g) >> 2;
uint256 h2 = h << 1;
do {
uint256 r = FixedPointMathLib.sqrt((s - c) * g);
sum += FixedPointMathLib.rawDiv(h2 * r, g);
} while (++s != end);
}
}
}
function linearSum(
uint128 linearPriceSlope,
uint32 fromSupply,
uint32 quantity
) internal pure returns (uint256 sum) {
// We don't need checked arithmetic for the sum because the max possible
// intermediate value is capped at:
// `k * m < 2**32 * 2**128 = 2**160 < 2**256`.
// As `quantity` is 32 bits, max possible value for `sum`
// is capped at:
// `2**32 * 2**160 = 2**192 < 2**256`.
// The result will be small enough for unchecked multiplication with a 16-bit BPS.
unchecked {
uint256 m = linearPriceSlope;
uint256 k = uint256(fromSupply);
uint256 n = k + uint256(quantity);
// Use the closed form to compute the sum.
return m * ((n * (n + 1) - k * (k + 1)) >> 1);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/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.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
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].
*
* CAUTION: See Security Considerations above.
*/
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.9.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
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or 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 {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// 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
pragma solidity ^0.8.4;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
library FixedPointMathLib {
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CUSTOM ERRORS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The operation failed, as the output exceeds the maximum value of uint256.
error ExpOverflow();
/// @dev The operation failed, as the output exceeds the maximum value of uint256.
error FactorialOverflow();
/// @dev The operation failed, due to an overflow.
error RPowOverflow();
/// @dev The mantissa is too big to fit.
error MantissaOverflow();
/// @dev The operation failed, due to an multiplication overflow.
error MulWadFailed();
/// @dev The operation failed, due to an multiplication overflow.
error SMulWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error DivWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error SDivWadFailed();
/// @dev The operation failed, either due to a multiplication overflow, or a division by a zero.
error MulDivFailed();
/// @dev The division failed, as the denominator is zero.
error DivFailed();
/// @dev The full precision multiply-divide operation failed, either due
/// to the result being larger than 256 bits, or a division by a zero.
error FullMulDivFailed();
/// @dev The output is undefined, as the input is less-than-or-equal to zero.
error LnWadUndefined();
/// @dev The input outside the acceptable domain.
error OutOfDomain();
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev The scalar of ETH and most ERC20s.
uint256 internal constant WAD = 1e18;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* SIMPLIFIED FIXED POINT OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Equivalent to `(x * y) / WAD` rounded down.
function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
if mul(y, gt(x, div(not(0), y))) {
mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down.
function sMulWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, y)
// Equivalent to `require((x == 0 || z / x == y) && !(x == -1 && y == type(int256).min))`.
if iszero(gt(or(iszero(x), eq(sdiv(z, x), y)), lt(not(x), eq(y, shl(255, 1))))) {
mstore(0x00, 0xedcd4dd4) // `SMulWadFailed()`.
revert(0x1c, 0x04)
}
z := sdiv(z, WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.
function rawMulWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded down, but without overflow checks.
function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(mul(x, y), WAD)
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded up.
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.
if mul(y, gt(x, div(not(0), y))) {
mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))
}
}
/// @dev Equivalent to `(x * y) / WAD` rounded up, but without overflow checks.
function rawMulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := add(iszero(iszero(mod(mul(x, y), WAD))), div(mul(x, y), WAD))
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down.
function divWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.
if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {
mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down.
function sDivWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(x, WAD)
// Equivalent to `require(y != 0 && ((x * WAD) / WAD == x))`.
if iszero(and(iszero(iszero(y)), eq(sdiv(z, WAD), x))) {
mstore(0x00, 0x5c43740d) // `SDivWadFailed()`.
revert(0x1c, 0x04)
}
z := sdiv(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.
function rawDivWad(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded down, but without overflow and divide by zero checks.
function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(mul(x, WAD), y)
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded up.
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.
if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {
mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))
}
}
/// @dev Equivalent to `(x * WAD) / y` rounded up, but without overflow and divide by zero checks.
function rawDivWadUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := add(iszero(iszero(mod(mul(x, WAD), y))), div(mul(x, WAD), y))
}
}
/// @dev Equivalent to `x` to the power of `y`.
/// because `x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y)`.
function powWad(int256 x, int256 y) internal pure returns (int256) {
// Using `ln(x)` means `x` must be greater than 0.
return expWad((lnWad(x) * y) / int256(WAD));
}
/// @dev Returns `exp(x)`, denominated in `WAD`.
/// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
function expWad(int256 x) internal pure returns (int256 r) {
unchecked {
// When the result is less than 0.5 we return zero.
// This happens when `x <= (log(1e-18) * 1e18) ~ -4.15e19`.
if (x <= -41446531673892822313) return r;
/// @solidity memory-safe-assembly
assembly {
// When the result is greater than `(2**255 - 1) / 1e18` we can not represent it as
// an int. This happens when `x >= floor(log((2**255 - 1) / 1e18) * 1e18) ≈ 135`.
if iszero(slt(x, 135305999368893231589)) {
mstore(0x00, 0xa37bfec9) // `ExpOverflow()`.
revert(0x1c, 0x04)
}
}
// `x` is now in the range `(-42, 136) * 1e18`. Convert to `(-42, 136) * 2**96`
// for more intermediate precision and a binary basis. This base conversion
// is a multiplication by 1e18 / 2**96 = 5**18 / 2**78.
x = (x << 78) / 5 ** 18;
// Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers
// of two such that exp(x) = exp(x') * 2**k, where k is an integer.
// Solving this gives k = round(x / log(2)) and x' = x - k * log(2).
int256 k = ((x << 96) / 54916777467707473351141471128 + 2 ** 95) >> 96;
x = x - k * 54916777467707473351141471128;
// `k` is in the range `[-61, 195]`.
// Evaluate using a (6, 7)-term rational approximation.
// `p` is made monic, we'll multiply by a scale factor later.
int256 y = x + 1346386616545796478920950773328;
y = ((y * x) >> 96) + 57155421227552351082224309758442;
int256 p = y + x - 94201549194550492254356042504812;
p = ((p * y) >> 96) + 28719021644029726153956944680412240;
p = p * x + (4385272521454847904659076985693276 << 96);
// We leave `p` in `2**192` basis so we don't need to scale it back up for the division.
int256 q = x - 2855989394907223263936484059900;
q = ((q * x) >> 96) + 50020603652535783019961831881945;
q = ((q * x) >> 96) - 533845033583426703283633433725380;
q = ((q * x) >> 96) + 3604857256930695427073651918091429;
q = ((q * x) >> 96) - 14423608567350463180887372962807573;
q = ((q * x) >> 96) + 26449188498355588339934803723976023;
/// @solidity memory-safe-assembly
assembly {
// Div in assembly because solidity adds a zero check despite the unchecked.
// The q polynomial won't have zeros in the domain as all its roots are complex.
// No scaling is necessary because p is already `2**96` too large.
r := sdiv(p, q)
}
// r should be in the range `(0.09, 0.25) * 2**96`.
// We now need to multiply r by:
// - The scale factor `s ≈ 6.031367120`.
// - The `2**k` factor from the range reduction.
// - The `1e18 / 2**96` factor for base conversion.
// We do this all at once, with an intermediate result in `2**213`
// basis, so the final right shift is always by a positive amount.
r = int256(
(uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)
);
}
}
/// @dev Returns `ln(x)`, denominated in `WAD`.
/// Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
function lnWad(int256 x) internal pure returns (int256 r) {
/// @solidity memory-safe-assembly
assembly {
// We want to convert `x` from `10**18` fixed point to `2**96` fixed point.
// We do this by multiplying by `2**96 / 10**18`. But since
// `ln(x * C) = ln(x) + ln(C)`, we can simply do nothing here
// and add `ln(2**96 / 10**18)` at the end.
// Compute `k = log2(x) - 96`, `r = 159 - k = 255 - log2(x) = 255 ^ log2(x)`.
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// We place the check here for more optimal stack operations.
if iszero(sgt(x, 0)) {
mstore(0x00, 0x1615e638) // `LnWadUndefined()`.
revert(0x1c, 0x04)
}
// forgefmt: disable-next-item
r := xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff))
// Reduce range of x to (1, 2) * 2**96
// ln(2^k * x) = k * ln(2) + ln(x)
x := shr(159, shl(r, x))
// Evaluate using a (8, 8)-term rational approximation.
// `p` is made monic, we will multiply by a scale factor later.
// forgefmt: disable-next-item
let p := sub( // This heavily nested expression is to avoid stack-too-deep for via-ir.
sar(96, mul(add(43456485725739037958740375743393,
sar(96, mul(add(24828157081833163892658089445524,
sar(96, mul(add(3273285459638523848632254066296,
x), x))), x))), x)), 11111509109440967052023855526967)
p := sub(sar(96, mul(p, x)), 45023709667254063763336534515857)
p := sub(sar(96, mul(p, x)), 14706773417378608786704636184526)
p := sub(mul(p, x), shl(96, 795164235651350426258249787498))
// We leave `p` in `2**192` basis so we don't need to scale it back up for the division.
// `q` is monic by convention.
let q := add(5573035233440673466300451813936, x)
q := add(71694874799317883764090561454958, sar(96, mul(x, q)))
q := add(283447036172924575727196451306956, sar(96, mul(x, q)))
q := add(401686690394027663651624208769553, sar(96, mul(x, q)))
q := add(204048457590392012362485061816622, sar(96, mul(x, q)))
q := add(31853899698501571402653359427138, sar(96, mul(x, q)))
q := add(909429971244387300277376558375, sar(96, mul(x, q)))
// `p / q` is in the range `(0, 0.125) * 2**96`.
// Finalization, we need to:
// - Multiply by the scale factor `s = 5.549…`.
// - Add `ln(2**96 / 10**18)`.
// - Add `k * ln(2)`.
// - Multiply by `10**18 / 2**96 = 5**18 >> 78`.
// The q polynomial is known not to have zeros in the domain.
// No scaling required because p is already `2**96` too large.
p := sdiv(p, q)
// Multiply by the scaling factor: `s * 5**18 * 2**96`, base is now `5**18 * 2**192`.
p := mul(1677202110996718588342820967067443963516166, p)
// Add `ln(2) * k * 5**18 * 2**192`.
// forgefmt: disable-next-item
p := add(mul(16597577552685614221487285958193947469193820559219878177908093499208371, sub(159, r)), p)
// Add `ln(2**96 / 10**18) * 5**18 * 2**192`.
p := add(600920179829731861736702779321621459595472258049074101567377883020018308, p)
// Base conversion: mul `2**18 / 2**192`.
r := sar(174, p)
}
}
/// @dev Returns `W_0(x)`, denominated in `WAD`.
/// See: https://en.wikipedia.org/wiki/Lambert_W_function
/// a.k.a. Product log function. This is an approximation of the principal branch.
function lambertW0Wad(int256 x) internal pure returns (int256 w) {
// forgefmt: disable-next-item
unchecked {
if ((w = x) <= -367879441171442322) revert OutOfDomain(); // `x` less than `-1/e`.
int256 wad = int256(WAD);
int256 p = x;
uint256 c; // Whether we need to avoid catastrophic cancellation.
uint256 i = 4; // Number of iterations.
if (w <= 0x1ffffffffffff) {
if (-0x4000000000000 <= w) {
i = 1; // Inputs near zero only take one step to converge.
} else if (w <= -0x3ffffffffffffff) {
i = 32; // Inputs near `-1/e` take very long to converge.
}
} else if (w >> 63 == 0) {
/// @solidity memory-safe-assembly
assembly {
// Inline log2 for more performance, since the range is small.
let v := shr(49, w)
let l := shl(3, lt(0xff, v))
l := add(or(l, byte(and(0x1f, shr(shr(l, v), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000)), 49)
w := sdiv(shl(l, 7), byte(sub(l, 31), 0x0303030303030303040506080c13))
c := gt(l, 60)
i := add(2, add(gt(l, 53), c))
}
} else {
int256 ll = lnWad(w = lnWad(w));
/// @solidity memory-safe-assembly
assembly {
// `w = ln(x) - ln(ln(x)) + b * ln(ln(x)) / ln(x)`.
w := add(sdiv(mul(ll, 1023715080943847266), w), sub(w, ll))
i := add(3, iszero(shr(68, x)))
c := iszero(shr(143, x))
}
if (c == 0) {
do { // If `x` is big, use Newton's so that intermediate values won't overflow.
int256 e = expWad(w);
/// @solidity memory-safe-assembly
assembly {
let t := mul(w, div(e, wad))
w := sub(w, sdiv(sub(t, x), div(add(e, t), wad)))
}
if (p <= w) break;
p = w;
} while (--i != 0);
/// @solidity memory-safe-assembly
assembly {
w := sub(w, sgt(w, 2))
}
return w;
}
}
do { // Otherwise, use Halley's for faster convergence.
int256 e = expWad(w);
/// @solidity memory-safe-assembly
assembly {
let t := add(w, wad)
let s := sub(mul(w, e), mul(x, wad))
w := sub(w, sdiv(mul(s, wad), sub(mul(e, t), sdiv(mul(add(t, wad), s), add(t, t)))))
}
if (p <= w) break;
p = w;
} while (--i != c);
/// @solidity memory-safe-assembly
assembly {
w := sub(w, sgt(w, 2))
}
// For certain ranges of `x`, we'll use the quadratic-rate recursive formula of
// R. Iacono and J.P. Boyd for the last iteration, to avoid catastrophic cancellation.
if (c != 0) {
int256 t = w | 1;
/// @solidity memory-safe-assembly
assembly {
x := sdiv(mul(x, wad), t)
}
x = (t * (wad + lnWad(x)));
/// @solidity memory-safe-assembly
assembly {
w := sdiv(x, add(wad, t))
}
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* GENERAL NUMBER UTILITIES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Calculates `floor(x * y / d)` with full precision.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv
function fullMulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
for {} 1 {} {
// 512-bit multiply `[p1 p0] = x * y`.
// Compute the product mod `2**256` and mod `2**256 - 1`
// then use the Chinese Remainder Theorem to reconstruct
// the 512 bit result. The result is stored in two 256
// variables such that `product = p1 * 2**256 + p0`.
// Least significant 256 bits of the product.
result := mul(x, y) // Temporarily use `result` as `p0` to save gas.
let mm := mulmod(x, y, not(0))
// Most significant 256 bits of the product.
let p1 := sub(mm, add(result, lt(mm, result)))
// Handle non-overflow cases, 256 by 256 division.
if iszero(p1) {
if iszero(d) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
result := div(result, d)
break
}
// Make sure the result is less than `2**256`. Also prevents `d == 0`.
if iszero(gt(d, p1)) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
/*------------------- 512 by 256 division --------------------*/
// Make division exact by subtracting the remainder from `[p1 p0]`.
// Compute remainder using mulmod.
let r := mulmod(x, y, d)
// `t` is the least significant bit of `d`.
// Always greater or equal to 1.
let t := and(d, sub(0, d))
// Divide `d` by `t`, which is a power of two.
d := div(d, t)
// Invert `d mod 2**256`
// Now that `d` is an odd number, it has an inverse
// modulo `2**256` such that `d * inv = 1 mod 2**256`.
// Compute the inverse by starting with a seed that is correct
// correct for four bits. That is, `d * inv = 1 mod 2**4`.
let inv := xor(2, mul(3, d))
// Now use Newton-Raphson iteration to improve the precision.
// Thanks to Hensel's lifting lemma, this also works in modular
// arithmetic, doubling the correct bits in each step.
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**8
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**16
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**32
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**64
inv := mul(inv, sub(2, mul(d, inv))) // inverse mod 2**128
result :=
mul(
// Divide [p1 p0] by the factors of two.
// Shift in bits from `p1` into `p0`. For this we need
// to flip `t` such that it is `2**256 / t`.
or(
mul(sub(p1, gt(r, result)), add(div(sub(0, t), t), 1)),
div(sub(result, r), t)
),
// inverse mod 2**256
mul(inv, sub(2, mul(d, inv)))
)
break
}
}
}
/// @dev Calculates `floor(x * y / d)` with full precision, rounded up.
/// Throws if result overflows a uint256 or when `d` is zero.
/// Credit to Uniswap-v3-core under MIT license:
/// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol
function fullMulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 result) {
result = fullMulDiv(x, y, d);
/// @solidity memory-safe-assembly
assembly {
if mulmod(x, y, d) {
result := add(result, 1)
if iszero(result) {
mstore(0x00, 0xae47f702) // `FullMulDivFailed()`.
revert(0x1c, 0x04)
}
}
}
}
/// @dev Returns `floor(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDiv(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := div(mul(x, y), d)
}
}
/// @dev Returns `ceil(x * y / d)`.
/// Reverts if `x * y` overflows, or `d` is zero.
function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// Equivalent to require(d != 0 && (y == 0 || x <= type(uint256).max / y))
if iszero(mul(d, iszero(mul(y, gt(x, div(not(0), y)))))) {
mstore(0x00, 0xad251c27) // `MulDivFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(mul(x, y), d))), div(mul(x, y), d))
}
}
/// @dev Returns `ceil(x / d)`.
/// Reverts if `d` is zero.
function divUp(uint256 x, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
if iszero(d) {
mstore(0x00, 0x65244e4e) // `DivFailed()`.
revert(0x1c, 0x04)
}
z := add(iszero(iszero(mod(x, d))), div(x, d))
}
}
/// @dev Returns `max(0, x - y)`.
function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(gt(x, y), sub(x, y))
}
}
/// @dev Exponentiate `x` to `y` by squaring, denominated in base `b`.
/// Reverts if the computation overflows.
function rpow(uint256 x, uint256 y, uint256 b) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mul(b, iszero(y)) // `0 ** 0 = 1`. Otherwise, `0 ** n = 0`.
if x {
z := xor(b, mul(xor(b, x), and(y, 1))) // `z = isEven(y) ? scale : x`
let half := shr(1, b) // Divide `b` by 2.
// Divide `y` by 2 every iteration.
for { y := shr(1, y) } y { y := shr(1, y) } {
let xx := mul(x, x) // Store x squared.
let xxRound := add(xx, half) // Round to the nearest number.
// Revert if `xx + half` overflowed, or if `x ** 2` overflows.
if or(lt(xxRound, xx), shr(128, x)) {
mstore(0x00, 0x49f7642b) // `RPowOverflow()`.
revert(0x1c, 0x04)
}
x := div(xxRound, b) // Set `x` to scaled `xxRound`.
// If `y` is odd:
if and(y, 1) {
let zx := mul(z, x) // Compute `z * x`.
let zxRound := add(zx, half) // Round to the nearest number.
// If `z * x` overflowed or `zx + half` overflowed:
if or(xor(div(zx, x), z), lt(zxRound, zx)) {
// Revert if `x` is non-zero.
if iszero(iszero(x)) {
mstore(0x00, 0x49f7642b) // `RPowOverflow()`.
revert(0x1c, 0x04)
}
}
z := div(zxRound, b) // Return properly scaled `zxRound`.
}
}
}
}
}
/// @dev Returns the square root of `x`.
function sqrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
// `floor(sqrt(2**15)) = 181`. `sqrt(2**15) - 181 = 2.84`.
z := 181 // The "correct" value is 1, but this saves a multiplication later.
// This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
// start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.
// Let `y = x / 2**r`. We check `y >= 2**(k + 8)`
// but shift right by `k` bits to ensure that if `x >= 256`, then `y >= 256`.
let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffffff, shr(r, x))))
z := shl(shr(1, r), z)
// Goal was to get `z*z*y` within a small factor of `x`. More iterations could
// get y in a tighter range. Currently, we will have y in `[256, 256*(2**16))`.
// We ensured `y >= 256` so that the relative difference between `y` and `y+1` is small.
// That's not possible if `x < 256` but we can just verify those cases exhaustively.
// Now, `z*z*y <= x < z*z*(y+1)`, and `y <= 2**(16+8)`, and either `y >= 256`, or `x < 256`.
// Correctness can be checked exhaustively for `x < 256`, so we assume `y >= 256`.
// Then `z*sqrt(y)` is within `sqrt(257)/sqrt(256)` of `sqrt(x)`, or about 20bps.
// For `s` in the range `[1/256, 256]`, the estimate `f(s) = (181/1024) * (s+1)`
// is in the range `(1/2.84 * sqrt(s), 2.84 * sqrt(s))`,
// with largest error when `s = 1` and when `s = 256` or `1/256`.
// Since `y` is in `[256, 256*(2**16))`, let `a = y/65536`, so that `a` is in `[1/256, 256)`.
// Then we can estimate `sqrt(y)` using
// `sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2**18`.
// There is no overflow risk here since `y < 2**136` after the first branch above.
z := shr(18, mul(z, add(shr(r, x), 65536))) // A `mul()` is saved from starting `z` at 181.
// Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// If `x+1` is a perfect square, the Babylonian method cycles between
// `floor(sqrt(x))` and `ceil(sqrt(x))`. This statement ensures we return floor.
// See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
z := sub(z, lt(div(x, z), z))
}
}
/// @dev Returns the cube root of `x`.
/// Credit to bout3fiddy and pcaversaccio under AGPLv3 license:
/// https://github.com/pcaversaccio/snekmate/blob/main/src/utils/Math.vy
function cbrt(uint256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
let r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
z := div(shl(div(r, 3), shl(lt(0xf, shr(r, x)), 0xf)), xor(7, mod(r, 3)))
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := div(add(add(div(x, mul(z, z)), z), z), 3)
z := sub(z, lt(div(x, mul(z, z)), z))
}
}
/// @dev Returns the square root of `x`, denominated in `WAD`.
function sqrtWad(uint256 x) internal pure returns (uint256 z) {
unchecked {
z = 10 ** 9;
if (x <= type(uint256).max / 10 ** 36 - 1) {
x *= 10 ** 18;
z = 1;
}
z *= sqrt(x);
}
}
/// @dev Returns the cube root of `x`, denominated in `WAD`.
function cbrtWad(uint256 x) internal pure returns (uint256 z) {
unchecked {
z = 10 ** 12;
if (x <= (type(uint256).max / 10 ** 36) * 10 ** 18 - 1) {
if (x >= type(uint256).max / 10 ** 36) {
x *= 10 ** 18;
z = 10 ** 6;
} else {
x *= 10 ** 36;
z = 1;
}
}
z *= cbrt(x);
}
}
/// @dev Returns the factorial of `x`.
function factorial(uint256 x) internal pure returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
if iszero(lt(x, 58)) {
mstore(0x00, 0xaba0f2a2) // `FactorialOverflow()`.
revert(0x1c, 0x04)
}
for { result := 1 } x { x := sub(x, 1) } { result := mul(result, x) }
}
}
/// @dev Returns the log2 of `x`.
/// Equivalent to computing the index of the most significant bit (MSB) of `x`.
/// Returns 0 if `x` is zero.
function log2(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(r, shl(3, lt(0xff, shr(r, x))))
// forgefmt: disable-next-item
r := or(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)),
0x0706060506020504060203020504030106050205030304010505030400000000))
}
}
/// @dev Returns the log2 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log2Up(uint256 x) internal pure returns (uint256 r) {
r = log2(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(shl(r, 1), x))
}
}
/// @dev Returns the log10 of `x`.
/// Returns 0 if `x` is zero.
function log10(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
if iszero(lt(x, 100000000000000000000000000000000000000)) {
x := div(x, 100000000000000000000000000000000000000)
r := 38
}
if iszero(lt(x, 100000000000000000000)) {
x := div(x, 100000000000000000000)
r := add(r, 20)
}
if iszero(lt(x, 10000000000)) {
x := div(x, 10000000000)
r := add(r, 10)
}
if iszero(lt(x, 100000)) {
x := div(x, 100000)
r := add(r, 5)
}
r := add(r, add(gt(x, 9), add(gt(x, 99), add(gt(x, 999), gt(x, 9999)))))
}
}
/// @dev Returns the log10 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log10Up(uint256 x) internal pure returns (uint256 r) {
r = log10(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(exp(10, r), x))
}
}
/// @dev Returns the log256 of `x`.
/// Returns 0 if `x` is zero.
function log256(uint256 x) internal pure returns (uint256 r) {
/// @solidity memory-safe-assembly
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x))))
r := or(r, shl(5, lt(0xffffffff, shr(r, x))))
r := or(r, shl(4, lt(0xffff, shr(r, x))))
r := or(shr(3, r), lt(0xff, shr(r, x)))
}
}
/// @dev Returns the log256 of `x`, rounded up.
/// Returns 0 if `x` is zero.
function log256Up(uint256 x) internal pure returns (uint256 r) {
r = log256(x);
/// @solidity memory-safe-assembly
assembly {
r := add(r, lt(shl(shl(3, r), 1), x))
}
}
/// @dev Returns the scientific notation format `mantissa * 10 ** exponent` of `x`.
/// Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).
function sci(uint256 x) internal pure returns (uint256 mantissa, uint256 exponent) {
/// @solidity memory-safe-assembly
assembly {
mantissa := x
if mantissa {
if iszero(mod(mantissa, 1000000000000000000000000000000000)) {
mantissa := div(mantissa, 1000000000000000000000000000000000)
exponent := 33
}
if iszero(mod(mantissa, 10000000000000000000)) {
mantissa := div(mantissa, 10000000000000000000)
exponent := add(exponent, 19)
}
if iszero(mod(mantissa, 1000000000000)) {
mantissa := div(mantissa, 1000000000000)
exponent := add(exponent, 12)
}
if iszero(mod(mantissa, 1000000)) {
mantissa := div(mantissa, 1000000)
exponent := add(exponent, 6)
}
if iszero(mod(mantissa, 10000)) {
mantissa := div(mantissa, 10000)
exponent := add(exponent, 4)
}
if iszero(mod(mantissa, 100)) {
mantissa := div(mantissa, 100)
exponent := add(exponent, 2)
}
if iszero(mod(mantissa, 10)) {
mantissa := div(mantissa, 10)
exponent := add(exponent, 1)
}
}
}
}
/// @dev Convenience function for packing `x` into a smaller number using `sci`.
/// The `mantissa` will be in bits [7..255] (the upper 249 bits).
/// The `exponent` will be in bits [0..6] (the lower 7 bits).
/// Use `SafeCastLib` to safely ensure that the `packed` number is small
/// enough to fit in the desired unsigned integer type:
/// ```
/// uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));
/// ```
function packSci(uint256 x) internal pure returns (uint256 packed) {
(x, packed) = sci(x); // Reuse for `mantissa` and `exponent`.
/// @solidity memory-safe-assembly
assembly {
if shr(249, x) {
mstore(0x00, 0xce30380c) // `MantissaOverflow()`.
revert(0x1c, 0x04)
}
packed := or(shl(7, x), packed)
}
}
/// @dev Convenience function for unpacking a packed number from `packSci`.
function unpackSci(uint256 packed) internal pure returns (uint256 unpacked) {
unchecked {
unpacked = (packed >> 7) * 10 ** (packed & 0x7f);
}
}
/// @dev Returns the average of `x` and `y`.
function avg(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = (x & y) + ((x ^ y) >> 1);
}
}
/// @dev Returns the average of `x` and `y`.
function avg(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = (x >> 1) + (y >> 1) + (x & y & 1);
}
}
/// @dev Returns the absolute value of `x`.
function abs(int256 x) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(sar(255, x), add(sar(255, x), x))
}
}
/// @dev Returns the absolute distance between `x` and `y`.
function dist(int256 x, int256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(mul(xor(sub(y, x), sub(x, y)), sgt(x, y)), sub(y, x))
}
}
/// @dev Returns the minimum of `x` and `y`.
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), lt(y, x)))
}
}
/// @dev Returns the minimum of `x` and `y`.
function min(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), slt(y, x)))
}
}
/// @dev Returns the maximum of `x` and `y`.
function max(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), gt(y, x)))
}
}
/// @dev Returns the maximum of `x` and `y`.
function max(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, y), sgt(y, x)))
}
}
/// @dev Returns `x`, bounded to `minValue` and `maxValue`.
function clamp(uint256 x, uint256 minValue, uint256 maxValue)
internal
pure
returns (uint256 z)
{
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, minValue), gt(minValue, x)))
z := xor(z, mul(xor(z, maxValue), lt(maxValue, z)))
}
}
/// @dev Returns `x`, bounded to `minValue` and `maxValue`.
function clamp(int256 x, int256 minValue, int256 maxValue) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := xor(x, mul(xor(x, minValue), sgt(minValue, x)))
z := xor(z, mul(xor(z, maxValue), slt(maxValue, z)))
}
}
/// @dev Returns greatest common divisor of `x` and `y`.
function gcd(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
for { z := x } y {} {
let t := y
y := mod(z, y)
z := t
}
}
}
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* RAW NUMBER OPERATIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
/// @dev Returns `x + y`, without checking for overflow.
function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x + y;
}
}
/// @dev Returns `x + y`, without checking for overflow.
function rawAdd(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x + y;
}
}
/// @dev Returns `x - y`, without checking for underflow.
function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x - y;
}
}
/// @dev Returns `x - y`, without checking for underflow.
function rawSub(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x - y;
}
}
/// @dev Returns `x * y`, without checking for overflow.
function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z) {
unchecked {
z = x * y;
}
}
/// @dev Returns `x * y`, without checking for overflow.
function rawMul(int256 x, int256 y) internal pure returns (int256 z) {
unchecked {
z = x * y;
}
}
/// @dev Returns `x / y`, returning 0 if `y` is zero.
function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := div(x, y)
}
}
/// @dev Returns `x / y`, returning 0 if `y` is zero.
function rawSDiv(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := sdiv(x, y)
}
}
/// @dev Returns `x % y`, returning 0 if `y` is zero.
function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mod(x, y)
}
}
/// @dev Returns `x % y`, returning 0 if `y` is zero.
function rawSMod(int256 x, int256 y) internal pure returns (int256 z) {
/// @solidity memory-safe-assembly
assembly {
z := smod(x, y)
}
}
/// @dev Returns `(x + y) % d`, return 0 if `d` if zero.
function rawAddMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := addmod(x, y, d)
}
}
/// @dev Returns `(x * y) % d`, return 0 if `d` if zero.
function rawMulMod(uint256 x, uint256 y, uint256 d) internal pure returns (uint256 z) {
/// @solidity memory-safe-assembly
assembly {
z := mulmod(x, y, d)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}{
"remappings": [
"contracts/=contracts/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"solady/=node_modules/solady/src/",
"forge-std/=node_modules/forge-std/src/",
"ds-test/src/=node_modules/ds-test/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"_ERC1155","type":"address"},{"internalType":"uint96","name":"_basePrice","type":"uint96"},{"internalType":"uint32","name":"_inflectionPoint","type":"uint32"},{"internalType":"uint128","name":"_inflectionPrice","type":"uint128"},{"internalType":"uint128","name":"_linearPriceSlope","type":"uint128"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint32","name":"quantity","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"totalPrice","type":"uint256"}],"name":"Buy","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ClaimYield","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAggregator","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"MigrateYield","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"indexed":true,"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAggregator","type":"address"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"QueueMigrateYield","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint32","name":"quantity","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"totalPrice","type":"uint256"}],"name":"Sell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"SetCurve","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"feePercent","type":"uint256"},{"indexed":false,"internalType":"string","name":"feeType","type":"string"}],"name":"SetFee","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ERC1155","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMELOCK_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"fromSupply","type":"uint32"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint96","name":"basePrice","type":"uint96"},{"internalType":"uint32","name":"inflectionPoint","type":"uint32"},{"internalType":"uint128","name":"inflectionPrice","type":"uint128"},{"internalType":"uint128","name":"linearPriceSlope","type":"uint128"}],"name":"_subTotal","outputs":[{"internalType":"uint256","name":"subTotal","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blankAggregator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"referral","type":"address"}],"name":"buyShare","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"claimYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"creatorFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"curvesMap","outputs":[{"internalType":"uint96","name":"basePrice","type":"uint96"},{"internalType":"uint128","name":"linearPriceSlope","type":"uint128"},{"internalType":"uint32","name":"inflectionPoint","type":"uint32"},{"internalType":"uint128","name":"inflectionPrice","type":"uint128"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositedETHAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"executeMigrateYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"referral","type":"address"}],"name":"getBuyPriceAfterFee","outputs":[{"internalType":"uint256","name":"buyPriceAfterFee","type":"uint256"},{"internalType":"uint256","name":"buyPrice","type":"uint256"},{"internalType":"uint256","name":"referralFee","type":"uint256"},{"internalType":"uint256","name":"creatorFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"getCurve","outputs":[{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"referral","type":"address"}],"name":"getSellPriceAfterFee","outputs":[{"internalType":"uint256","name":"sellPriceAfterFee","type":"uint256"},{"internalType":"uint256","name":"sellPrice","type":"uint256"},{"internalType":"uint256","name":"referralFee","type":"uint256"},{"internalType":"uint256","name":"creatorFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"}],"name":"getShare","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint8","name":"curveType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"fromSupply","type":"uint32"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"getSubTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"migrationDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"curveType","type":"uint8"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"address","name":"referral","type":"address"}],"name":"mintAndBuyShare","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"curveType","type":"uint8"}],"name":"mintShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingAggregator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_yieldAggregator","type":"address"}],"name":"queueMigrateYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"referralFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_yieldAggregator","type":"address"}],"name":"resetYield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"},{"internalType":"uint32","name":"quantity","type":"uint32"},{"internalType":"uint256","name":"minETHAmount","type":"uint256"},{"internalType":"address","name":"referral","type":"address"}],"name":"sellShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setCreatorFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_curveType","type":"uint8"},{"internalType":"uint96","name":"_basePrice","type":"uint96"},{"internalType":"uint32","name":"_inflectionPoint","type":"uint32"},{"internalType":"uint128","name":"_inflectionPrice","type":"uint128"},{"internalType":"uint128","name":"_linearPriceSlope","type":"uint128"}],"name":"setCurveType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feePercent","type":"uint256"}],"name":"setReferralFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shareIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shareId","type":"uint256"}],"name":"sharesMap","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint8","name":"curveType","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yieldAggregator","outputs":[{"internalType":"contract IYieldAggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a060405266b1a2bc2ec5000060075566b1a2bc2ec5000060085534801561002657600080fd5b506040516129eb3803806129eb833981016040819052610045916101f3565b61004e3361016b565b600160028190556001600160a01b0390951660809081526040805160a0810182526001600160601b0396871681526001600160801b03938416602080830191825263ffffffff97881693830193845295851660608301908152938201988952600080526004909552517f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec805495519251909616600160e01b026001600160e01b039285166c01000000000000000000000000026001600160e01b03199096169190971617939093179290921693909317909155517f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ed805493511515600160801b026001600160881b03199094169190921617919091179055610281565b600180546001600160a01b031916905561018481610187565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160801b03811681146101ee57600080fd5b919050565b600080600080600060a0868803121561020b57600080fd5b85516001600160a01b038116811461022257600080fd5b60208701519095506001600160601b038116811461023f57600080fd5b604087015190945063ffffffff8116811461025957600080fd5b9250610267606087016101d7565b9150610275608087016101d7565b90509295509295909350565b60805161272c6102bf6000396000818161030c015281816107b601528181610a65015281816113020152818161144a015261174e015261272c6000f3fe6080604052600436106101e55760003560e01c80636483da0e11610101578063a57d4fd21161009a578063cfb5a5f81161006c578063cfb5a5f814610694578063e2319c29146106b4578063e30c3978146106d4578063e5f6d99e146106f2578063f2fde38b1461071257005b8063a57d4fd2146105db578063add5e5bd1461063e578063c56ad1ad1461065e578063c985a7601461067457005b806379d023ae116100d357806379d023ae146104d057806383924de0146104f05780638da5cb5b146105065780638f9fb4301461052457005b80636483da0e146104735780636ff6c4b814610486578063715018a6146104a657806379ba5097146104bb57005b80632e48842c1161017e5780634cd14dc6116101505780634cd14dc61461039857806352e00d7d146103b857806353613dd3146103d85780635919a89f146103ee578063614524e21461045357005b80632e48842c1461032e57806344fe98f9146103415780634623c81e14610361578063479a877a1461037857005b8063291dda3c116101b7578063291dda3c146102855780632a194b6d146102c55780632a2b8beb146102e55780632d255471146102fa57005b806313c9440b146101ee57806315f63f9e146102175780631fdb5f531461024f57806326cd86481461026557005b366101ec57005b005b3480156101fa57600080fd5b5061020460075481565b6040519081526020015b60405180910390f35b34801561022357600080fd5b50600c54610237906001600160a01b031681565b6040516001600160a01b03909116815260200161020e565b34801561025b57600080fd5b5061020460065481565b34801561027157600080fd5b50610204610280366004612295565b610732565b34801561029157600080fd5b506102a56102a036600461231e565b610780565b60408051948552602085019390935291830152606082015260800161020e565b3480156102d157600080fd5b50600a54610237906001600160a01b031681565b3480156102f157600080fd5b506101ec6108b2565b34801561030657600080fd5b506102377f000000000000000000000000000000000000000000000000000000000000000081565b6101ec61033c36600461231e565b61098c565b34801561034d57600080fd5b50600b54610237906001600160a01b031681565b34801561036d57600080fd5b506102046203f48081565b34801561038457600080fd5b506101ec61039336600461236f565b610bf7565b3480156103a457600080fd5b506101ec6103b33660046123d4565b610ddd565b3480156103c457600080fd5b506101ec6103d3366004612404565b610f4e565b3480156103e457600080fd5b5061020460085481565b3480156103fa57600080fd5b5061040e610409366004612404565b611050565b604080516001600160601b03909616865263ffffffff90941660208601526001600160801b03928316938501939093521660608301521515608082015260a00161020e565b34801561045f57600080fd5b506101ec61046e366004612426565b611147565b6101ec61048136600461243f565b6111ac565b34801561049257600080fd5b506101ec6104a1366004612426565b6111ce565b3480156104b257600080fd5b506101ec611227565b3480156104c757600080fd5b506101ec61123b565b3480156104dc57600080fd5b506101ec6104eb36600461246b565b6112b5565b3480156104fc57600080fd5b5061020460095481565b34801561051257600080fd5b506000546001600160a01b0316610237565b34801561053057600080fd5b5061059361053f366004612404565b600460205260009081526040902080546001909101546001600160601b03821691600160601b81046001600160801b0390811692600160e01b90920463ffffffff169190811690600160801b900460ff1685565b604080516001600160601b0390961686526001600160801b03948516602087015263ffffffff909316928501929092529190911660608301521515608082015260a00161020e565b3480156105e757600080fd5b5061061d6105f6366004612426565b6003602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b03909316835260ff90911660208301520161020e565b34801561064a57600080fd5b506101ec6106593660046124b3565b6115a8565b34801561066a57600080fd5b5061020460055481565b34801561068057600080fd5b506101ec61068f3660046124b3565b61161f565b3480156106a057600080fd5b5061061d6106af366004612426565b6116b5565b3480156106c057600080fd5b506102a56106cf36600461231e565b611718565b3480156106e057600080fd5b506001546001600160a01b0316610237565b3480156106fe57600080fd5b5061020461070d3660046124d0565b61188c565b34801561071e57600080fd5b506101ec61072d3660046124b3565b6118c0565b63ffffffff8581168581026001600160601b0316916001600160801b0384169089166001818101820291909301808401020390911c020161077584848989611931565b019695505050505050565b6000806000806000610791886116b5565b60405163d2cf911560e01b8152600481018b9052909250600091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d2cf911590602401602060405180830381865afa1580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108219190612513565b905060006001600160a01b03881661083a57600061083e565b6007545b905061084b828a8561188c565b9550670de0b6b3a76400006108608288612542565b61086a919061255f565b9450670de0b6b3a7640000600854876108839190612542565b61088d919061255f565b93508361089a8688612581565b6108a49190612581565b965050505093509350935093565b6108ba611a8d565b600b546001600160a01b03166109175760405162461bcd60e51b815260206004820152601960248201527f496e76616c69642070656e64696e6741676772656761746f720000000000000060448201526064015b60405180910390fd5b6009544210156109605760405162461bcd60e51b8152602060048201526014602482015273151a5b595b1bd8dac81b9bdd08195e1c1a5c995960621b604482015260640161090e565b600b54610975906001600160a01b0316611ae7565b600b80546001600160a01b03191690556000600955565b610994611bd3565b600a546001600160a01b03166109bc5760405162461bcd60e51b815260040161090e90612594565b60055483106109dd5760405162461bcd60e51b815260040161090e906125cb565b6000806000806109ee878787610780565b935093509350935083341015610a3d5760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015260640161090e565b60405163106fcedf60e21b81523360048201526024810188905263ffffffff871660448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906341bf3b7c90606401600060405180830381600087803b158015610ab157600080fd5b505af1158015610ac5573d6000803e3d6000fd5b50506040805163ffffffff8a168152602081018890523393508a92507fd629f65aad3876b36909246fcad04b828345d3c3859ae8ef22024c701c638dda910160405180910390a3600a54610b22906001600160a01b031684611c2a565b600a60009054906101000a90046001600160a01b03166001600160a01b031663bb282e5c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b505050508260066000828254610b9c9190612581565b9091555060009050610bad886116b5565b509050610bba8183611c2a565b610bc48684611c2a565b6000610bd086346125f4565b90508015610be257610be23382611c2a565b505050505050610bf26001600255565b505050565b610bff611a8d565b60ff808616600090815260046020526040902060010154600160801b90041615610c6b5760405162461bcd60e51b815260206004820152601960248201527f437572766520616c726561647920696e697469616c697a656400000000000000604482015260640161090e565b60006040518060a00160405280866001600160601b03168152602001836001600160801b031681526020018563ffffffff168152602001846001600160801b0316815260200160011515815250905080600460008860ff1660ff16815260200190815260200160002060008201518160000160006101000a8154816001600160601b0302191690836001600160601b03160217905550602082015181600001600c6101000a8154816001600160801b0302191690836001600160801b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160006101000a8154816001600160801b0302191690836001600160801b0316021790555060808201518160010160106101000a81548160ff0219169083151502179055509050508560ff167f26db86cda55dac43ee3e55ae8fc7e7adbcc478300763e1f9f60f01f9fc51487160405160405180910390a2505050505050565b610de5611a8d565b600a546006546040516328e762dd60e01b815260048101919091526000916001600160a01b0316906328e762dd90602401602060405180830381865afa158015610e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e579190612513565b905080831115610e9e5760405162461bcd60e51b8152602060048201526012602482015271125b9cdd59999a58da595b9d081e5a595b1960721b604482015260640161090e565b600a546040516316d7ac4560e31b8152600481018590526001600160a01b039091169063b6bd622890602401600060405180830381600087803b158015610ee457600080fd5b505af1158015610ef8573d6000803e3d6000fd5b50505050610f068284611c2a565b816001600160a01b03167fc82fd9ebea57700479e05121ad619652619f27f7d29858cdae6682fda41fe55284604051610f4191815260200190565b60405180910390a2505050565b60ff808216600090815260046020526040902060010154600160801b900416610fad5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063757276655479706560781b604482015260640161090e565b6040805180820182523380825260ff80851660208085018281526005805460009081526003909352878320875181549351909616600160a01b026001600160a81b03199093166001600160a01b03969096169590951791909117909355915494519394909390917fa8d59a1f2271ecc5d7752782185c1434ea96ddea72ca66855434ef1ecd253ee191a46005805490600061104783612607565b91905055505050565b60ff80821660009081526004602052604081206001015490918291829182918291600160801b909104166110ba5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063757276655479706560781b604482015260640161090e565b5050505060ff918216600090815260046020908152604091829020825160a08101845281546001600160601b038116808352600160601b82046001600160801b03908116958401869052600160e01b90920463ffffffff1695830186905260019093015490811660608301819052600160801b909104909616151560809091018190529095929493509091565b61114f611a8d565b80600781905550807fc7d813e57ac72d4e8776f37f3bf28d0ac1798575c8119fc2ec1b12db853a2ac86040516111a1906020808252600890820152671c9959995c9c985b60c21b604082015260600190565b60405180910390a250565b6111b583610f4e565b610bf260016005546111c791906125f4565b838361098c565b6111d6611a8d565b80600881905550807fc7d813e57ac72d4e8776f37f3bf28d0ac1798575c8119fc2ec1b12db853a2ac86040516111a19060208082526007908201526631b932b0ba37b960c91b604082015260600190565b61122f611a8d565b6112396000611ce7565b565b60015433906001600160a01b031681146112a95760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161090e565b6112b281611ce7565b50565b6112bd611bd3565b60055484106112de5760405162461bcd60e51b815260040161090e906125cb565b6040516327e662e160e21b81523360048201526024810185905263ffffffff8416907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639f998b8490604401602060405180830381865afa158015611351573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113759190612513565b10156113b95760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742073686172657360681b604482015260640161090e565b6000806000806113ca888887611718565b9350935093509350858410156114225760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e74206d696e52656365697665000000000000000000604482015260640161090e565b6040516317a99ced60e31b81523360048201526024810189905263ffffffff881660448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd4ce76890606401600060405180830381600087803b15801561149657600080fd5b505af11580156114aa573d6000803e3d6000fd5b50506040805163ffffffff8b168152602081018890523393508b92507f10823adf12ea857cee76cfabdea04b0c493c2dc620fabad557295f5b9355576d910160405180910390a3600a546040516316d7ac4560e31b8152600481018590526001600160a01b039091169063b6bd622890602401600060405180830381600087803b15801561153757600080fd5b505af115801561154b573d6000803e3d6000fd5b50505050826006600082825461156191906125f4565b9091555061157190503385611c2a565b600061157c896116b5565b5090506115898183611c2a565b6115938684611c2a565b50505050506115a26001600255565b50505050565b6115b0611a8d565b6001600160a01b0381166115d65760405162461bcd60e51b815260040161090e90612594565b600a546001600160a01b031661160a57600c80546001600160a01b0319166001600160a01b0383161790556112b281611d00565b600c546112b2906001600160a01b0316611ae7565b611627611a8d565b6001600160a01b03811661164d5760405162461bcd60e51b815260040161090e90612594565b600b80546001600160a01b0319166001600160a01b0383161790556116756203f48042612581565b60098190556040519081526001600160a01b038216907fa04791e6e2a61a31610862e90bffabb149ea33f1da3e1cb1d21bdb74fb4a2cc3906020016111a1565b60008060055483106116d95760405162461bcd60e51b815260040161090e906125cb565b50506000908152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910460ff169290910182905291565b6000806000806000611729886116b5565b60405163d2cf911560e01b8152600481018b9052909250600091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063d2cf911590602401602060405180830381865afa158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b99190612513565b905060006001600160a01b0388166117d25760006117d6565b6007545b90508863ffffffff1682101561181f5760405162461bcd60e51b815260206004820152600e60248201526d4578636565647320737570706c7960901b604482015260640161090e565b61183361182c8a84612620565b8a8561188c565b9550670de0b6b3a76400006118488288612542565b611852919061255f565b9450670de0b6b3a76400006008548761186b9190612542565b611875919061255f565b93508361188286886125f4565b6108a491906125f4565b600080600080600061189d86611050565b5093509350935093506118b4888886868686610732565b98975050505050505050565b6118c8611a8d565b600180546001600160a01b0383166001600160a01b031990911681179091556118f96000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600063ffffffff85166001600160801b038516808202830361195857600092505050611a85565b600163ffffffff868116828101929187160101838118818511028418808310156119b8576006600163ffffffff8a16818101026401fffffffe8b831b16820102600019840180850290831b90920191909102030485800285040295509150815b81831015611a7f576003850260021c600185901b5b6000611a63888488030270ffffffffffffffffffffffffffffffffff811160071b81811c68ffffffffffffffffff1060061b1781811c64ffffffffff1060051b1781811c62ffffff1060041b1781811c620100000160b5600192831c1b0260121c80830401811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c908190048111900390565b8202889004989098019750600180860195859003016119cd5750505b50505050505b949350505050565b6000546001600160a01b031633146112395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090e565b611aef611d98565b600a54604080516376d5de8560e01b815290516000926001600160a01b0316916376d5de859160048083019260209291908290030181865afa158015611b39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5d9190612644565b600a54909150611b7b906001600160a01b0380841691166000611e67565b611b8482611d00565b611b8c611f9e565b816001600160a01b03167ff18e48d1af2253ee9e1af0b85bd910610f450e46bf010260206c1eabc743089042604051611bc791815260200190565b60405180910390a25050565b6002805403611c245760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161090e565b60028055565b8015611ce357604080516000808252602082019092526001600160a01b038416908390604051611c5a9190612685565b60006040518083038185875af1925050503d8060008114611c97576040519150601f19603f3d011682016040523d82523d6000602084013e611c9c565b606091505b5050905080610bf25760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161090e565b5050565b600180546001600160a01b03191690556112b281612006565b600a80546001600160a01b0319166001600160a01b038316908117909155604080516376d5de8560e01b81529051600092916376d5de859160048083019260209291908290030181865afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d809190612644565b9050611ce36001600160a01b03821683600019611e67565b600a54604051638812ebc960e01b81523060048201526000916001600160a01b031690638812ebc990602401602060405180830381865afa158015611de1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e059190612513565b600a546040516316d7ac4560e31b8152600481018390529192506001600160a01b03169063b6bd622890602401600060405180830381600087803b158015611e4c57600080fd5b505af1158015611e60573d6000803e3d6000fd5b5050505050565b801580611ee15750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edf9190612513565b155b611f4c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161090e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610bf2908490612056565b600a544790611fb6906001600160a01b031682611c2a565b600a60009054906101000a90046001600160a01b03166001600160a01b031663bb282e5c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e4c57600080fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006120ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661212b9092919063ffffffff16565b90508051600014806120cc5750808060200190518101906120cc91906126a1565b610bf25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161090e565b6060611a85848460008585600080866001600160a01b031685876040516121529190612685565b60006040518083038185875af1925050503d806000811461218f576040519150601f19603f3d011682016040523d82523d6000602084013e612194565b606091505b50915091506121a5878383876121b0565b979650505050505050565b6060831561221f578251600003612218576001600160a01b0385163b6122185760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161090e565b5081611a85565b611a8583838151156122345781518083602001fd5b8060405162461bcd60e51b815260040161090e91906126c3565b803563ffffffff8116811461226257600080fd5b919050565b80356001600160601b038116811461226257600080fd5b80356001600160801b038116811461226257600080fd5b60008060008060008060c087890312156122ae57600080fd5b6122b78761224e565b95506122c56020880161224e565b94506122d360408801612267565b93506122e16060880161224e565b92506122ef6080880161227e565b91506122fd60a0880161227e565b90509295509295509295565b6001600160a01b03811681146112b257600080fd5b60008060006060848603121561233357600080fd5b833592506123436020850161224e565b9150604084013561235381612309565b809150509250925092565b803560ff8116811461226257600080fd5b600080600080600060a0868803121561238757600080fd5b6123908661235e565b945061239e60208701612267565b93506123ac6040870161224e565b92506123ba6060870161227e565b91506123c86080870161227e565b90509295509295909350565b600080604083850312156123e757600080fd5b8235915060208301356123f981612309565b809150509250929050565b60006020828403121561241657600080fd5b61241f8261235e565b9392505050565b60006020828403121561243857600080fd5b5035919050565b60008060006060848603121561245457600080fd5b61245d8461235e565b92506123436020850161224e565b6000806000806080858703121561248157600080fd5b843593506124916020860161224e565b92506040850135915060608501356124a881612309565b939692955090935050565b6000602082840312156124c557600080fd5b813561241f81612309565b6000806000606084860312156124e557600080fd5b6124ee8461224e565b92506124fc6020850161224e565b915061250a6040850161235e565b90509250925092565b60006020828403121561252557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176125595761255961252c565b92915050565b60008261257c57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156125595761255961252c565b60208082526017908201527f496e76616c6964207969656c6441676772656761746f72000000000000000000604082015260600190565b6020808252600f908201526e125b9d985b1a59081cda185c995259608a1b604082015260600190565b818103818111156125595761255961252c565b6000600182016126195761261961252c565b5060010190565b63ffffffff82811682821603908082111561263d5761263d61252c565b5092915050565b60006020828403121561265657600080fd5b815161241f81612309565b60005b8381101561267c578181015183820152602001612664565b50506000910152565b60008251612697818460208701612661565b9190910192915050565b6000602082840312156126b357600080fd5b8151801515811461241f57600080fd5b60208152600082518060208401526126e2816040850160208701612661565b601f01601f1916919091016040019291505056fea26469706673582212208335563ded97a0d1a47268bfe0338beebad97e3c8538b98e21a705c8da8fe41764736f6c634300081900330000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd44824580000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000005dc000000000000000000000000000000000000000000000000016c2734f97a40000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101e55760003560e01c80636483da0e11610101578063a57d4fd21161009a578063cfb5a5f81161006c578063cfb5a5f814610694578063e2319c29146106b4578063e30c3978146106d4578063e5f6d99e146106f2578063f2fde38b1461071257005b8063a57d4fd2146105db578063add5e5bd1461063e578063c56ad1ad1461065e578063c985a7601461067457005b806379d023ae116100d357806379d023ae146104d057806383924de0146104f05780638da5cb5b146105065780638f9fb4301461052457005b80636483da0e146104735780636ff6c4b814610486578063715018a6146104a657806379ba5097146104bb57005b80632e48842c1161017e5780634cd14dc6116101505780634cd14dc61461039857806352e00d7d146103b857806353613dd3146103d85780635919a89f146103ee578063614524e21461045357005b80632e48842c1461032e57806344fe98f9146103415780634623c81e14610361578063479a877a1461037857005b8063291dda3c116101b7578063291dda3c146102855780632a194b6d146102c55780632a2b8beb146102e55780632d255471146102fa57005b806313c9440b146101ee57806315f63f9e146102175780631fdb5f531461024f57806326cd86481461026557005b366101ec57005b005b3480156101fa57600080fd5b5061020460075481565b6040519081526020015b60405180910390f35b34801561022357600080fd5b50600c54610237906001600160a01b031681565b6040516001600160a01b03909116815260200161020e565b34801561025b57600080fd5b5061020460065481565b34801561027157600080fd5b50610204610280366004612295565b610732565b34801561029157600080fd5b506102a56102a036600461231e565b610780565b60408051948552602085019390935291830152606082015260800161020e565b3480156102d157600080fd5b50600a54610237906001600160a01b031681565b3480156102f157600080fd5b506101ec6108b2565b34801561030657600080fd5b506102377f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd448245881565b6101ec61033c36600461231e565b61098c565b34801561034d57600080fd5b50600b54610237906001600160a01b031681565b34801561036d57600080fd5b506102046203f48081565b34801561038457600080fd5b506101ec61039336600461236f565b610bf7565b3480156103a457600080fd5b506101ec6103b33660046123d4565b610ddd565b3480156103c457600080fd5b506101ec6103d3366004612404565b610f4e565b3480156103e457600080fd5b5061020460085481565b3480156103fa57600080fd5b5061040e610409366004612404565b611050565b604080516001600160601b03909616865263ffffffff90941660208601526001600160801b03928316938501939093521660608301521515608082015260a00161020e565b34801561045f57600080fd5b506101ec61046e366004612426565b611147565b6101ec61048136600461243f565b6111ac565b34801561049257600080fd5b506101ec6104a1366004612426565b6111ce565b3480156104b257600080fd5b506101ec611227565b3480156104c757600080fd5b506101ec61123b565b3480156104dc57600080fd5b506101ec6104eb36600461246b565b6112b5565b3480156104fc57600080fd5b5061020460095481565b34801561051257600080fd5b506000546001600160a01b0316610237565b34801561053057600080fd5b5061059361053f366004612404565b600460205260009081526040902080546001909101546001600160601b03821691600160601b81046001600160801b0390811692600160e01b90920463ffffffff169190811690600160801b900460ff1685565b604080516001600160601b0390961686526001600160801b03948516602087015263ffffffff909316928501929092529190911660608301521515608082015260a00161020e565b3480156105e757600080fd5b5061061d6105f6366004612426565b6003602052600090815260409020546001600160a01b03811690600160a01b900460ff1682565b604080516001600160a01b03909316835260ff90911660208301520161020e565b34801561064a57600080fd5b506101ec6106593660046124b3565b6115a8565b34801561066a57600080fd5b5061020460055481565b34801561068057600080fd5b506101ec61068f3660046124b3565b61161f565b3480156106a057600080fd5b5061061d6106af366004612426565b6116b5565b3480156106c057600080fd5b506102a56106cf36600461231e565b611718565b3480156106e057600080fd5b506001546001600160a01b0316610237565b3480156106fe57600080fd5b5061020461070d3660046124d0565b61188c565b34801561071e57600080fd5b506101ec61072d3660046124b3565b6118c0565b63ffffffff8581168581026001600160601b0316916001600160801b0384169089166001818101820291909301808401020390911c020161077584848989611931565b019695505050505050565b6000806000806000610791886116b5565b60405163d2cf911560e01b8152600481018b9052909250600091506001600160a01b037f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd4482458169063d2cf911590602401602060405180830381865afa1580156107fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108219190612513565b905060006001600160a01b03881661083a57600061083e565b6007545b905061084b828a8561188c565b9550670de0b6b3a76400006108608288612542565b61086a919061255f565b9450670de0b6b3a7640000600854876108839190612542565b61088d919061255f565b93508361089a8688612581565b6108a49190612581565b965050505093509350935093565b6108ba611a8d565b600b546001600160a01b03166109175760405162461bcd60e51b815260206004820152601960248201527f496e76616c69642070656e64696e6741676772656761746f720000000000000060448201526064015b60405180910390fd5b6009544210156109605760405162461bcd60e51b8152602060048201526014602482015273151a5b595b1bd8dac81b9bdd08195e1c1a5c995960621b604482015260640161090e565b600b54610975906001600160a01b0316611ae7565b600b80546001600160a01b03191690556000600955565b610994611bd3565b600a546001600160a01b03166109bc5760405162461bcd60e51b815260040161090e90612594565b60055483106109dd5760405162461bcd60e51b815260040161090e906125cb565b6000806000806109ee878787610780565b935093509350935083341015610a3d5760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b604482015260640161090e565b60405163106fcedf60e21b81523360048201526024810188905263ffffffff871660448201527f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd44824586001600160a01b0316906341bf3b7c90606401600060405180830381600087803b158015610ab157600080fd5b505af1158015610ac5573d6000803e3d6000fd5b50506040805163ffffffff8a168152602081018890523393508a92507fd629f65aad3876b36909246fcad04b828345d3c3859ae8ef22024c701c638dda910160405180910390a3600a54610b22906001600160a01b031684611c2a565b600a60009054906101000a90046001600160a01b03166001600160a01b031663bb282e5c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b7257600080fd5b505af1158015610b86573d6000803e3d6000fd5b505050508260066000828254610b9c9190612581565b9091555060009050610bad886116b5565b509050610bba8183611c2a565b610bc48684611c2a565b6000610bd086346125f4565b90508015610be257610be23382611c2a565b505050505050610bf26001600255565b505050565b610bff611a8d565b60ff808616600090815260046020526040902060010154600160801b90041615610c6b5760405162461bcd60e51b815260206004820152601960248201527f437572766520616c726561647920696e697469616c697a656400000000000000604482015260640161090e565b60006040518060a00160405280866001600160601b03168152602001836001600160801b031681526020018563ffffffff168152602001846001600160801b0316815260200160011515815250905080600460008860ff1660ff16815260200190815260200160002060008201518160000160006101000a8154816001600160601b0302191690836001600160601b03160217905550602082015181600001600c6101000a8154816001600160801b0302191690836001600160801b03160217905550604082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060608201518160010160006101000a8154816001600160801b0302191690836001600160801b0316021790555060808201518160010160106101000a81548160ff0219169083151502179055509050508560ff167f26db86cda55dac43ee3e55ae8fc7e7adbcc478300763e1f9f60f01f9fc51487160405160405180910390a2505050505050565b610de5611a8d565b600a546006546040516328e762dd60e01b815260048101919091526000916001600160a01b0316906328e762dd90602401602060405180830381865afa158015610e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e579190612513565b905080831115610e9e5760405162461bcd60e51b8152602060048201526012602482015271125b9cdd59999a58da595b9d081e5a595b1960721b604482015260640161090e565b600a546040516316d7ac4560e31b8152600481018590526001600160a01b039091169063b6bd622890602401600060405180830381600087803b158015610ee457600080fd5b505af1158015610ef8573d6000803e3d6000fd5b50505050610f068284611c2a565b816001600160a01b03167fc82fd9ebea57700479e05121ad619652619f27f7d29858cdae6682fda41fe55284604051610f4191815260200190565b60405180910390a2505050565b60ff808216600090815260046020526040902060010154600160801b900416610fad5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063757276655479706560781b604482015260640161090e565b6040805180820182523380825260ff80851660208085018281526005805460009081526003909352878320875181549351909616600160a01b026001600160a81b03199093166001600160a01b03969096169590951791909117909355915494519394909390917fa8d59a1f2271ecc5d7752782185c1434ea96ddea72ca66855434ef1ecd253ee191a46005805490600061104783612607565b91905055505050565b60ff80821660009081526004602052604081206001015490918291829182918291600160801b909104166110ba5760405162461bcd60e51b8152602060048201526011602482015270496e76616c69642063757276655479706560781b604482015260640161090e565b5050505060ff918216600090815260046020908152604091829020825160a08101845281546001600160601b038116808352600160601b82046001600160801b03908116958401869052600160e01b90920463ffffffff1695830186905260019093015490811660608301819052600160801b909104909616151560809091018190529095929493509091565b61114f611a8d565b80600781905550807fc7d813e57ac72d4e8776f37f3bf28d0ac1798575c8119fc2ec1b12db853a2ac86040516111a1906020808252600890820152671c9959995c9c985b60c21b604082015260600190565b60405180910390a250565b6111b583610f4e565b610bf260016005546111c791906125f4565b838361098c565b6111d6611a8d565b80600881905550807fc7d813e57ac72d4e8776f37f3bf28d0ac1798575c8119fc2ec1b12db853a2ac86040516111a19060208082526007908201526631b932b0ba37b960c91b604082015260600190565b61122f611a8d565b6112396000611ce7565b565b60015433906001600160a01b031681146112a95760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b606482015260840161090e565b6112b281611ce7565b50565b6112bd611bd3565b60055484106112de5760405162461bcd60e51b815260040161090e906125cb565b6040516327e662e160e21b81523360048201526024810185905263ffffffff8416907f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd44824586001600160a01b031690639f998b8490604401602060405180830381865afa158015611351573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113759190612513565b10156113b95760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742073686172657360681b604482015260640161090e565b6000806000806113ca888887611718565b9350935093509350858410156114225760405162461bcd60e51b815260206004820152601760248201527f496e73756666696369656e74206d696e52656365697665000000000000000000604482015260640161090e565b6040516317a99ced60e31b81523360048201526024810189905263ffffffff881660448201527f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd44824586001600160a01b03169063bd4ce76890606401600060405180830381600087803b15801561149657600080fd5b505af11580156114aa573d6000803e3d6000fd5b50506040805163ffffffff8b168152602081018890523393508b92507f10823adf12ea857cee76cfabdea04b0c493c2dc620fabad557295f5b9355576d910160405180910390a3600a546040516316d7ac4560e31b8152600481018590526001600160a01b039091169063b6bd622890602401600060405180830381600087803b15801561153757600080fd5b505af115801561154b573d6000803e3d6000fd5b50505050826006600082825461156191906125f4565b9091555061157190503385611c2a565b600061157c896116b5565b5090506115898183611c2a565b6115938684611c2a565b50505050506115a26001600255565b50505050565b6115b0611a8d565b6001600160a01b0381166115d65760405162461bcd60e51b815260040161090e90612594565b600a546001600160a01b031661160a57600c80546001600160a01b0319166001600160a01b0383161790556112b281611d00565b600c546112b2906001600160a01b0316611ae7565b611627611a8d565b6001600160a01b03811661164d5760405162461bcd60e51b815260040161090e90612594565b600b80546001600160a01b0319166001600160a01b0383161790556116756203f48042612581565b60098190556040519081526001600160a01b038216907fa04791e6e2a61a31610862e90bffabb149ea33f1da3e1cb1d21bdb74fb4a2cc3906020016111a1565b60008060055483106116d95760405162461bcd60e51b815260040161090e906125cb565b50506000908152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910460ff169290910182905291565b6000806000806000611729886116b5565b60405163d2cf911560e01b8152600481018b9052909250600091506001600160a01b037f0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd4482458169063d2cf911590602401602060405180830381865afa158015611795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b99190612513565b905060006001600160a01b0388166117d25760006117d6565b6007545b90508863ffffffff1682101561181f5760405162461bcd60e51b815260206004820152600e60248201526d4578636565647320737570706c7960901b604482015260640161090e565b61183361182c8a84612620565b8a8561188c565b9550670de0b6b3a76400006118488288612542565b611852919061255f565b9450670de0b6b3a76400006008548761186b9190612542565b611875919061255f565b93508361188286886125f4565b6108a491906125f4565b600080600080600061189d86611050565b5093509350935093506118b4888886868686610732565b98975050505050505050565b6118c8611a8d565b600180546001600160a01b0383166001600160a01b031990911681179091556118f96000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600063ffffffff85166001600160801b038516808202830361195857600092505050611a85565b600163ffffffff868116828101929187160101838118818511028418808310156119b8576006600163ffffffff8a16818101026401fffffffe8b831b16820102600019840180850290831b90920191909102030485800285040295509150815b81831015611a7f576003850260021c600185901b5b6000611a63888488030270ffffffffffffffffffffffffffffffffff811160071b81811c68ffffffffffffffffff1060061b1781811c64ffffffffff1060051b1781811c62ffffff1060041b1781811c620100000160b5600192831c1b0260121c80830401811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c908190048111900390565b8202889004989098019750600180860195859003016119cd5750505b50505050505b949350505050565b6000546001600160a01b031633146112395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161090e565b611aef611d98565b600a54604080516376d5de8560e01b815290516000926001600160a01b0316916376d5de859160048083019260209291908290030181865afa158015611b39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b5d9190612644565b600a54909150611b7b906001600160a01b0380841691166000611e67565b611b8482611d00565b611b8c611f9e565b816001600160a01b03167ff18e48d1af2253ee9e1af0b85bd910610f450e46bf010260206c1eabc743089042604051611bc791815260200190565b60405180910390a25050565b6002805403611c245760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161090e565b60028055565b8015611ce357604080516000808252602082019092526001600160a01b038416908390604051611c5a9190612685565b60006040518083038185875af1925050503d8060008114611c97576040519150601f19603f3d011682016040523d82523d6000602084013e611c9c565b606091505b5050905080610bf25760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161090e565b5050565b600180546001600160a01b03191690556112b281612006565b600a80546001600160a01b0319166001600160a01b038316908117909155604080516376d5de8560e01b81529051600092916376d5de859160048083019260209291908290030181865afa158015611d5c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d809190612644565b9050611ce36001600160a01b03821683600019611e67565b600a54604051638812ebc960e01b81523060048201526000916001600160a01b031690638812ebc990602401602060405180830381865afa158015611de1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e059190612513565b600a546040516316d7ac4560e31b8152600481018390529192506001600160a01b03169063b6bd622890602401600060405180830381600087803b158015611e4c57600080fd5b505af1158015611e60573d6000803e3d6000fd5b5050505050565b801580611ee15750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015611ebb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611edf9190612513565b155b611f4c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161090e565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610bf2908490612056565b600a544790611fb6906001600160a01b031682611c2a565b600a60009054906101000a90046001600160a01b03166001600160a01b031663bb282e5c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e4c57600080fd5b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006120ab826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661212b9092919063ffffffff16565b90508051600014806120cc5750808060200190518101906120cc91906126a1565b610bf25760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161090e565b6060611a85848460008585600080866001600160a01b031685876040516121529190612685565b60006040518083038185875af1925050503d806000811461218f576040519150601f19603f3d011682016040523d82523d6000602084013e612194565b606091505b50915091506121a5878383876121b0565b979650505050505050565b6060831561221f578251600003612218576001600160a01b0385163b6122185760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161090e565b5081611a85565b611a8583838151156122345781518083602001fd5b8060405162461bcd60e51b815260040161090e91906126c3565b803563ffffffff8116811461226257600080fd5b919050565b80356001600160601b038116811461226257600080fd5b80356001600160801b038116811461226257600080fd5b60008060008060008060c087890312156122ae57600080fd5b6122b78761224e565b95506122c56020880161224e565b94506122d360408801612267565b93506122e16060880161224e565b92506122ef6080880161227e565b91506122fd60a0880161227e565b90509295509295509295565b6001600160a01b03811681146112b257600080fd5b60008060006060848603121561233357600080fd5b833592506123436020850161224e565b9150604084013561235381612309565b809150509250925092565b803560ff8116811461226257600080fd5b600080600080600060a0868803121561238757600080fd5b6123908661235e565b945061239e60208701612267565b93506123ac6040870161224e565b92506123ba6060870161227e565b91506123c86080870161227e565b90509295509295909350565b600080604083850312156123e757600080fd5b8235915060208301356123f981612309565b809150509250929050565b60006020828403121561241657600080fd5b61241f8261235e565b9392505050565b60006020828403121561243857600080fd5b5035919050565b60008060006060848603121561245457600080fd5b61245d8461235e565b92506123436020850161224e565b6000806000806080858703121561248157600080fd5b843593506124916020860161224e565b92506040850135915060608501356124a881612309565b939692955090935050565b6000602082840312156124c557600080fd5b813561241f81612309565b6000806000606084860312156124e557600080fd5b6124ee8461224e565b92506124fc6020850161224e565b915061250a6040850161235e565b90509250925092565b60006020828403121561252557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176125595761255961252c565b92915050565b60008261257c57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156125595761255961252c565b60208082526017908201527f496e76616c6964207969656c6441676772656761746f72000000000000000000604082015260600190565b6020808252600f908201526e125b9d985b1a59081cda185c995259608a1b604082015260600190565b818103818111156125595761255961252c565b6000600182016126195761261961252c565b5060010190565b63ffffffff82811682821603908082111561263d5761263d61252c565b5092915050565b60006020828403121561265657600080fd5b815161241f81612309565b60005b8381101561267c578181015183820152602001612664565b50506000910152565b60008251612697818460208701612661565b9190910192915050565b6000602082840312156126b357600080fd5b8151801515811461241f57600080fd5b60208152600082518060208401526126e2816040850160208701612661565b601f01601f1916919091016040019291505056fea26469706673582212208335563ded97a0d1a47268bfe0338beebad97e3c8538b98e21a705c8da8fe41764736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd44824580000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000005dc000000000000000000000000000000000000000000000000016c2734f97a40000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _ERC1155 (address): 0x7662CA69bF777F66040E53f9F5e5a5DFd4482458
Arg [1] : _basePrice (uint96): 5000000000000000
Arg [2] : _inflectionPoint (uint32): 1500
Arg [3] : _inflectionPrice (uint128): 102500000000000000
Arg [4] : _linearPriceSlope (uint128): 0
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000007662ca69bf777f66040e53f9f5e5a5dfd4482458
Arg [1] : 0000000000000000000000000000000000000000000000000011c37937e08000
Arg [2] : 00000000000000000000000000000000000000000000000000000000000005dc
Arg [3] : 000000000000000000000000000000000000000000000000016c2734f97a4000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.