Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- VestingMulticall
- Optimization enabled
- true
- Compiler version
- v0.8.20+commit.a1b79de6
- Optimization runs
- 200
- EVM Version
- shanghai
- Verified at
- 2026-01-18T07:41:28.818836Z
Constructor Arguments
0x0000000000000000000000006fabb568bb71041d92b4e541eb99eba3598c5a21
Arg [0] (address) : 0x6fabb568bb71041d92b4e541eb99eba3598c5a21
src/constants/contracts/viewcaVest.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
interface ICryptoForAll {
function thisDay() external view returns (uint256);
function vesting(
address user,
uint256 day
)
external
view
returns (
uint256 vestTime,
uint256 amount,
uint256 claimed,
uint256 lastUpdate,
uint256 collected
);
function calcVestingEmission(
address user,
uint256 day
) external view returns (uint256);
function readVestingEmission(
address user,
uint256 day
) external view returns (uint256);
function auctionEntry_thatDay(uint256 day) external view returns (uint256);
function buyBackAndBuildDone(uint256 day) external view returns (bool);
function mapMemberAuction(
address user,
uint256 day
)
external
view
returns (uint256 memberAuctionValue, bool hasChangedShareToToken);
function calculateTokenPerShareOnDay(
uint256 day
) external view returns (uint256);
function oneDay() external view returns (uint256);
function auctionPeriod() external view returns (uint256);
}
contract VestingMulticall {
// Combine related data to reduce stack variables
struct VestingData {
uint256 day;
uint256 amount;
uint256 claimed;
uint256 vestTime;
uint256 lastUpdate;
uint256 collected;
bool isValid;
}
struct UserVestingData {
uint256 totalDays;
VestingData[] vestingDetails;
}
struct AuctionData {
uint256 day;
uint256 userDeposit;
uint256 totalDeposits;
bool hasChangedShareToToken;
bool buyBackAndBuildDone;
uint256 tokenPerShare;
uint256 pendingEmission;
}
address public owner;
ICryptoForAll public cryptoForAll;
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
constructor(address _cryptoForAll) {
owner = msg.sender;
cryptoForAll = ICryptoForAll(_cryptoForAll);
}
function setCryptoForAll(address _cryptoForAll) external onlyOwner {
cryptoForAll = ICryptoForAll(_cryptoForAll);
}
/**
* @notice Get all vesting data for a user in a single call
* @param user Address of the user
* @param startDay First day to fetch (usually 1)
* @param endDay Last day to fetch (can be current day)
* @return A struct containing all vesting data for the specified days
*/
function getUserVestingStats(
address user,
uint256 startDay,
uint256 endDay
) external view returns (UserVestingData memory) {
require(startDay > 0, "Start day must be greater than 0");
// Limit end day to the current day
uint256 currentDay = cryptoForAll.thisDay();
if (endDay > currentDay) {
endDay = currentDay;
}
// First pass: count valid entries
uint256 validCount = 0;
for (uint256 day = startDay; day <= endDay; day++) {
(uint256 vestTime, , , , ) = cryptoForAll.vesting(user, day);
if (vestTime > 0) {
validCount++;
}
}
// Create result with proper size
UserVestingData memory userData = UserVestingData({
totalDays: validCount,
vestingDetails: new VestingData[](validCount)
});
// Only if we have valid entries, populate the array
if (validCount > 0) {
uint256 index = 0;
for (
uint256 day = startDay;
day <= endDay && index < validCount;
day++
) {
(
uint256 vestTime,
uint256 amount,
uint256 claimed,
uint256 lastUpdate,
uint256 collected
) = cryptoForAll.vesting(user, day);
if (vestTime > 0) {
// Split into two operations to reduce stack depth
userData.vestingDetails[index].day = day;
userData.vestingDetails[index].amount = amount;
userData.vestingDetails[index].claimed = cryptoForAll
.calcVestingEmission(user, day);
userData.vestingDetails[index].vestTime = vestTime;
userData.vestingDetails[index].lastUpdate = lastUpdate;
userData.vestingDetails[index].collected = collected;
userData.vestingDetails[index].isValid = true;
index++;
}
}
}
return userData;
}
/**
* @notice Get vesting data for specific days (for pagination)
* @param user Address of the user
* @param _days Array of days to fetch data for
* @return Array of VestingData for the specified days
*/
function getVestingDataForDays(
address user,
uint256[] calldata _days
) external view returns (VestingData[] memory) {
VestingData[] memory results = new VestingData[](_days.length);
for (uint256 i = 0; i < _days.length; i++) {
uint256 day = _days[i];
// Get vesting data - split into multiple statements
(
uint256 vestTime,
uint256 amount,
uint256 claimed,
uint256 lastUpdate,
uint256 collected
) = cryptoForAll.vesting(user, day);
// Populate data fields one by one to reduce stack usage
results[i].day = day;
results[i].amount = amount;
results[i].vestTime = vestTime;
results[i].lastUpdate = lastUpdate;
results[i].collected = collected;
results[i].isValid = vestTime > 0;
// Only calculate emission if there's a valid vesting
if (vestTime > 0) {
results[i].claimed = cryptoForAll.calcVestingEmission(
user,
day
);
} else {
results[i].claimed = 0;
}
}
return results;
}
/**
* @notice Get auction data for a user within a range of days
* @param user Address of the user
* @param startDay First day to fetch
* @param endDay Last day to fetch
* @return Array of AuctionData for the specified days
*/
function getUserAuctionData(
address user,
uint256 startDay,
uint256 endDay
) external view returns (AuctionData[] memory) {
require(startDay > 0, "Start day must be greater than 0");
// Validate input
uint256 currentDay = cryptoForAll.thisDay();
if (endDay > currentDay) {
endDay = currentDay;
}
uint256 daysCount = endDay - startDay + 1;
AuctionData[] memory auctionData = new AuctionData[](daysCount);
// Process each day
for (uint256 i = 0; i < daysCount; i++) {
uint256 day = startDay + i;
// Split data gathering into multiple statements
(
uint256 memberAuctionValue,
bool hasChangedShareToToken
) = cryptoForAll.mapMemberAuction(user, day);
// Populate data fields one by one
auctionData[i].day = day;
auctionData[i].userDeposit = memberAuctionValue;
auctionData[i].totalDeposits = cryptoForAll.auctionEntry_thatDay(
day
);
auctionData[i].hasChangedShareToToken = hasChangedShareToToken;
auctionData[i].buyBackAndBuildDone = cryptoForAll
.buyBackAndBuildDone(day);
auctionData[i].tokenPerShare = cryptoForAll
.calculateTokenPerShareOnDay(day);
// Only calculate emission if shares were changed to tokens
if (hasChangedShareToToken) {
auctionData[i].pendingEmission = cryptoForAll
.calcVestingEmission(user, day);
} else {
auctionData[i].pendingEmission = 0;
}
}
return auctionData;
}
/**
* @notice Get the current vesting day
* @return Current day from the CryptoForAll contract
*/
function getCurrentDay() external view returns (uint256) {
return cryptoForAll.thisDay();
}
/**
* @notice Count how many valid vesting entries a user has
* @param user Address of the user
* @return Total count of valid vesting entries
*/
function countUserVestingEntries(
address user
) external view returns (uint256) {
uint256 currentDay = cryptoForAll.thisDay();
uint256 count = 0;
for (uint256 day = 1; day <= currentDay; day++) {
(uint256 vestTime, , , , ) = cryptoForAll.vesting(user, day);
if (vestTime > 0) {
count++;
}
}
return count;
}
/**
* @notice Get vesting data for a specific page (with pagination)
* @param user Address of the user
* @param pageSize Number of items per page
* @param pageNumber Page number (starting from 1)
* @return Array of VestingData for the specified page and total pages
*/
function getVestingDataPaginated(
address user,
uint256 pageSize,
uint256 pageNumber
) external view returns (VestingData[] memory, uint256) {
require(pageNumber > 0, "Page number must be greater than 0");
require(pageSize > 0, "Page size must be greater than 0");
// First collect valid days (reducing local vars by using more memory)
uint256[] memory validDays = _collectValidDays(user);
uint256 validCount = 0;
// Count valid days (separate loop to reduce stack)
for (uint256 i = 0; i < validDays.length; i++) {
if (validDays[i] > 0) validCount++;
else break; // We stored days sequentially, so first 0 means end
}
// Early return if no data
if (validCount == 0) {
return (new VestingData[](0), 0);
}
// Calculate pagination parameters
uint256 totalPages = (validCount + pageSize - 1) / pageSize; // Ceiling division
pageNumber = pageNumber > totalPages ? totalPages : pageNumber;
uint256 startIndex = (pageNumber - 1) * pageSize;
uint256 itemsToFetch = pageSize;
if (startIndex + itemsToFetch > validCount) {
itemsToFetch = validCount - startIndex;
}
// Create and populate result
VestingData[] memory results = new VestingData[](itemsToFetch);
for (uint256 i = 0; i < itemsToFetch; i++) {
_populateVestingData(results, i, user, validDays[startIndex + i]);
}
return (results, totalPages);
}
/**
* @notice Helper function to collect valid days with vesting data
* @param user User address to check
* @return Array of day numbers with valid vesting data (0 means no data)
*/
function _collectValidDays(
address user
) private view returns (uint256[] memory) {
uint256 currentDay = cryptoForAll.thisDay();
uint256[] memory _days = new uint256[](currentDay);
uint256 count = 0;
for (uint256 day = 1; day <= currentDay; day++) {
(uint256 vestTime, , , , ) = cryptoForAll.vesting(user, day);
if (vestTime > 0) {
_days[count] = day;
count++;
}
}
return _days;
}
/**
* @notice Helper function to populate vesting data (reduces stack usage)
* @param results Array to populate
* @param index Index in the array
* @param user User address
* @param day Day to fetch data for
*/
function _populateVestingData(
VestingData[] memory results,
uint256 index,
address user,
uint256 day
) private view {
// Get vesting data
(
uint256 vestTime,
uint256 amount,
uint256 claimed,
uint256 lastUpdate,
uint256 collected
) = cryptoForAll.vesting(user, day);
// Populate struct fields one by one
results[index].day = day;
results[index].amount = amount;
results[index].vestTime = vestTime;
results[index].lastUpdate = lastUpdate;
results[index].collected = collected;
results[index].isValid = true;
results[index].claimed = cryptoForAll.calcVestingEmission(user, day);
}
/**
* @notice Get important contract constants in a single call
* @return oneDay Period of one day in seconds
* @return auctionPeriod Total auction period in seconds
* @return currentDay Current day number
*/
function getContractConstants()
external
view
returns (uint256 oneDay, uint256 auctionPeriod, uint256 currentDay)
{
return (
cryptoForAll.oneDay(),
cryptoForAll.auctionPeriod(),
cryptoForAll.thisDay()
);
}
}
Compiler Settings
{"viaIR":true,"remappings":["forge-std/=lib/forge-std/src/"],"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"metadata":{"useLiteralContent":false,"bytecodeHash":"ipfs","appendCBOR":true},"libraries":{},"evmVersion":"shanghai"}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_cryptoForAll","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"countUserVestingEntries","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICryptoForAll"}],"name":"cryptoForAll","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"oneDay","internalType":"uint256"},{"type":"uint256","name":"auctionPeriod","internalType":"uint256"},{"type":"uint256","name":"currentDay","internalType":"uint256"}],"name":"getContractConstants","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCurrentDay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct VestingMulticall.AuctionData[]","components":[{"type":"uint256","name":"day","internalType":"uint256"},{"type":"uint256","name":"userDeposit","internalType":"uint256"},{"type":"uint256","name":"totalDeposits","internalType":"uint256"},{"type":"bool","name":"hasChangedShareToToken","internalType":"bool"},{"type":"bool","name":"buyBackAndBuildDone","internalType":"bool"},{"type":"uint256","name":"tokenPerShare","internalType":"uint256"},{"type":"uint256","name":"pendingEmission","internalType":"uint256"}]}],"name":"getUserAuctionData","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"startDay","internalType":"uint256"},{"type":"uint256","name":"endDay","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct VestingMulticall.UserVestingData","components":[{"type":"uint256","name":"totalDays","internalType":"uint256"},{"type":"tuple[]","name":"vestingDetails","internalType":"struct VestingMulticall.VestingData[]","components":[{"type":"uint256","name":"day","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"claimed","internalType":"uint256"},{"type":"uint256","name":"vestTime","internalType":"uint256"},{"type":"uint256","name":"lastUpdate","internalType":"uint256"},{"type":"uint256","name":"collected","internalType":"uint256"},{"type":"bool","name":"isValid","internalType":"bool"}]}]}],"name":"getUserVestingStats","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"startDay","internalType":"uint256"},{"type":"uint256","name":"endDay","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct VestingMulticall.VestingData[]","components":[{"type":"uint256","name":"day","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"claimed","internalType":"uint256"},{"type":"uint256","name":"vestTime","internalType":"uint256"},{"type":"uint256","name":"lastUpdate","internalType":"uint256"},{"type":"uint256","name":"collected","internalType":"uint256"},{"type":"bool","name":"isValid","internalType":"bool"}]}],"name":"getVestingDataForDays","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256[]","name":"_days","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple[]","name":"","internalType":"struct VestingMulticall.VestingData[]","components":[{"type":"uint256","name":"day","internalType":"uint256"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"claimed","internalType":"uint256"},{"type":"uint256","name":"vestTime","internalType":"uint256"},{"type":"uint256","name":"lastUpdate","internalType":"uint256"},{"type":"uint256","name":"collected","internalType":"uint256"},{"type":"bool","name":"isValid","internalType":"bool"}]},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getVestingDataPaginated","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"pageSize","internalType":"uint256"},{"type":"uint256","name":"pageNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCryptoForAll","inputs":[{"type":"address","name":"_cryptoForAll","internalType":"address"}]}]
Contract Creation Code
0x60803461007857601f61168b38819003918201601f19168301916001600160401b0383118484101761007c5780849260209460405283398101031261007857516001600160a01b038116908190036100785760018060a01b031933815f5416175f5560015416176001556040516115fa90816100918239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b60e05f35811c9182633c11abb414610d56575081633e6968b614610cd65781634844e11014610c5b57816351c1e94d146107fe5750806355ab7b45146105f15780638da5cb5b146105ca5780638e98465e14610498578063ad6f2efe14610470578063e6bfd81f146104385763e7b4a0731461008c575f80fd5b3461030f5761009a36610e81565b91908290606060206040516100ae81610f30565b5f815201526100be811515610f82565b60015460405163bf627bf560e01b81526001600160a01b039091169490602081600481895afa90811561031b575f91610406575b508091116103fe575b505f93815b83811115610377575061011285611062565b946040519561012087610f30565b818752602087015280610190575b50505050506040518091602082526020606083019180518285015201519060408084015281518091526020608084019201905f5b818110610170575050500390f35b9193509160206101836001928651610eab565b9401910191849392610162565b5f9592939495935b858111158061036e575b1561035d5760405163143ee5b960e01b81526001600160a01b03881660048201526024810182905260a081604481875afa801561031b575f915f80915f93610326575b50836101fe575b505050506101f990610fcd565b610198565b846102118a60208b9c97989c01516110b1565b5152602061022285828b01516110b1565b510152604051638f10aca760e01b81526001600160a01b038b166004820152602481018990526020816044818a5afa90811561031b575f916102db575b50906101f994849392604061027b6102d19760208d01516110b1565b510152606061028e8560208c01516110b1565b51015260806102a18460208b01516110b1565b51015260a06102b48360208a01516110b1565b510152600160c06102c98360208a01516110b1565b510152610fcd565b94905f80806101ec565b93929190506020843d602011610313575b816102f960209383610f60565b8101031261030f579251919290916101f961025f565b5f80fd5b3d91506102ec565b6040513d5f823e3d90fd5b9250505061034c915060a03d60a011610356575b6103448183610f60565b810190610fdb565b915090915f6101e5565b503d61033a565b505050925050505f8080808061012e565b508185106101a2565b60405163143ee5b960e01b81526001600160a01b03861660048201526024810182905260a0908181604481875afa91821561031b575f926103dd575b50506103c8575b6103c390610fcd565b610100565b946103d56103c391610fcd565b9590506103ba565b6103f39250803d10610356576103448183610f60565b505050505f806103b3565b91505f6100fb565b90506020813d602011610430575b8161042160209383610f60565b8101031261030f57515f6100f2565b3d9150610414565b3461030f5761046661045261044c36610e81565b91611100565b604051928392604084526040840190610ef4565b9060208301520390f35b3461030f575f36600319011261030f576001546040516001600160a01b039091168152602090f35b3461030f575f36600319011261030f57600154604051634bd9351b60e01b81526001600160a01b039091169060208082600481865afa91821561031b575f9261059b575b506040516301999f8b60e31b8152928184600481845afa93841561031b575f9461056c575b5092816004946040519586809263bf627bf560e01b82525afa91821561031b575f9261053c575b606094506040519384528301526040820152f35b80925084813d8311610565575b6105538183610f60565b8101031261030f576060935191610528565b503d610549565b93508184813d8311610594575b6105838183610f60565b8101031261030f5792519281610501565b503d610579565b9080925081813d83116105c3575b6105b38183610f60565b8101031261030f575190836104dc565b503d6105a9565b3461030f575f36600319011261030f575f546040516001600160a01b039091168152602090f35b3461030f57604036600319011261030f5761060a610e6b565b602480359067ffffffffffffffff80831161030f573660238401121561030f57826004013590811161030f57600591368183851b8601011161030f57610651829392611062565b60015490946001600160a01b03909116925f5b85811061068557604051602080825281906106819082018a610ef4565b0390f35b60405163143ee5b960e01b81526001600160a01b038916600482015281831b840185013560248201819052919060a080826044818b5afa801561031b575f915f93858d5f925f956107c7575b5081818a6106e460809561070c956110b1565b5152602098896106f484846110b1565b51015287606061070484846110b1565b5101526110b1565b510152610719858d6110b1565b51015215158060c061072b858d6110b1565b510152156107b457604051638f10aca760e01b81526001600160a01b038b166004820152602481019390935280836044818a5afa90811561031b575f91610784575b5061077f925060406102c9838b6110b1565b610664565b905082813d83116107ad575b61079a8183610f60565b8101031261030f5761077f91518a61076d565b503d610790565b5061077f91505f60406102c9838b6110b1565b90945061070c96506107eb91955060809250833d8511610356576103448183610f60565b92985092969195929391929190506106d1565b3461030f5761080c36610e81565b929091908361081c841515610f82565b60019260018060a01b038454169160405163bf627bf560e01b81526020978882600481885afa801561031b5788925f91610c26575b50806108639411610c1e575b506110d9565b91848301809311610c0a5761087b8397969597611002565b946108896040519687610f60565b838652601f1961089885611002565b015f5b818110610bed5750505f5b84811061093457505050505060405193838594850190808652845180925280604087019501935f905b8382106108dc5787870388f35b85518051885280840151888501526040808201519089015260608082015115159089015260808082015115159089015260a0808201519089015260c090810151908801528897509586019594820194908401906108cf565b61094281839a98999a6110e6565b6040805163262cffef60e11b81526001600160a01b0387166004820152602481018390529192919081604481885afa90811561031b575f905f92610bad575b508361098d848d6110b1565b51528b61099a848d6110b1565b510152604051635ccbff4160e11b815260048101849052602491908c8184818a5afa90811561031b578c85915f93610b7b575b506040916109da916110b1565b51015260606109e9848d6110b1565b51821515910152604051631585119960e01b8152600481018590528c8184818a5afa90811561031b578c85915f93610b3a575b50608091610a29916110b1565b510190151590528b6040518093633a52bedd60e01b825286600483015281895afa801561031b57838c8e945f93610b04575b5060a091610a68916110b1565b51015215610af157604051638f10aca760e01b81526001600160a01b0387166004820152602481019390935282604481875afa801561031b575f90610ac2575b610ab9925060c06102c9838c6110b1565b979695976108a6565b508982813d8311610aea575b610ad88183610f60565b8101031261030f57610ab99151610aa8565b503d610ace565b50610ab991505f60c06102c9838c6110b1565b949250505082813d8311610b33575b610b1d8183610f60565b8101031261030f5790518b9190838c60a0610a5b565b503d610b13565b925050508c81813d8311610b74575b610b538183610f60565b8101031261030f576080610a2985610b6b8f946110f3565b93915091610a1c565b503d610b49565b925050508c81813d8311610ba6575b610b948183610f60565b8101031261030f5751838c60406109cd565b503d610b8a565b9150506040813d604011610be5575b81610bc960409383610f60565b8101031261030f57610bde8b825192016110f3565b908c610981565b3d9150610bbc565b9780999798610bfa61101a565b82828c010152019897969861089b565b634e487b7160e01b5f52601160045260245ffd5b90508961085d565b8093508a8092503d8311610c54575b610c3f8183610f60565b8101031261030f579051879190610863610851565b503d610c35565b3461030f57602036600319011261030f57610c74610e6b565b5f546001600160a01b03919082163303610ca557166bffffffffffffffffffffffff60a01b60015416176001555f80f35b60405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606490fd5b3461030f575f36600319011261030f5760015460405163bf627bf560e01b815290602090829060049082906001600160a01b03165afa801561031b575f90610d24575b602090604051908152f35b506020813d8211610d4e575b81610d3d60209383610f60565b8101031261030f5760209051610d19565b3d9150610d30565b3461030f5760208060031936011261030f57610d70610e6b565b60015463bf627bf560e01b84526001600160a01b03168284600481845afa93841561031b575f94610e3c575b505f9160015b85811115610db557505050604051908152f35b60405163143ee5b960e01b81526001600160a01b03831660048201526024810182905260a0908181604481885afa91821561031b575f92610e1b575b5050610e06575b610e0190610fcd565b610da2565b92610e13610e0191610fcd565b939050610df8565b610e319250803d10610356576103448183610f60565b505050508780610df1565b9093508281813d8311610e64575b610e548183610f60565b8101031261030f57519284610d9c565b503d610e4a565b600435906001600160a01b038216820361030f57565b606090600319011261030f576004356001600160a01b038116810361030f57906024359060443590565b9060c060e092805183526020810151602084015260408101516040840152606081015160608401526080810151608084015260a081015160a08401520151151560c08201520190565b9081518082526020808093019301915f5b828110610f13575050505090565b9091929382610f256001928751610eab565b950193929101610f05565b6040810190811067ffffffffffffffff821117610f4c57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610f4c57604052565b15610f8957565b606460405162461bcd60e51b815260206004820152602060248201527f537461727420646179206d7573742062652067726561746572207468616e20306044820152fd5b5f198114610c0a5760010190565b908160a091031261030f578051916020820151916040810151916080606083015192015190565b67ffffffffffffffff8111610f4c5760051b60200190565b6040519060e0820182811067ffffffffffffffff821117610f4c576040528160c05f918281528260208201528260408201528260608201528260808201528260a08201520152565b9061106c82611002565b6110796040519182610f60565b828152809261108a601f1991611002565b01905f5b82811061109a57505050565b6020906110a561101a565b8282850101520161108e565b80518210156110c55760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b91908203918211610c0a57565b91908201809211610c0a57565b5190811515820361030f57565b90929192831561157457801561153057600180546040805163bf627bf560e01b81529460209391926001600160a01b031690600485888281865afa978815611526575f986114f7575b5061115388611002565b976111608651998a610f60565b808952601f1961116f82611002565b0136888b01375f855b8281111561144d575050505f978489905b611414575b5088156113d35761119f888a6110e6565b5f1999908a81019081116113c0578990049b8c8111156113ba57508b995b8a01998a116113a757888a0299808b048a14901517156113a757808a916111e48b846110e6565b11611394575b50506111f588611062565b985f5b89811061120d57505050505050505050509190565b61122061121a82846110e6565b846110b1565b51885163143ee5b960e01b81526001600160a01b0387168682019081526020810183905260a09081908390819060400103818c5afa91821561138a5760c08f868f95916112be928f95966112f299975f8081928295611361575b508a61128688886110b1565b51528b61129388886110b1565b51015260606112a287876110b1565b51015260806112b186866110b1565b51015261070484846110b1565b5101528a51638f10aca760e01b81526001600160a01b03891688820190815260208101929092529283918291604090910190565b03818a5afa9081156113575790898d93925f9261131d575b506102c983611318956110b1565b6111f8565b809394508c8092503d8311611350575b6113378183610f60565b8101031261134d5750518b9190896102c961130a565b80fd5b503d61132d565b89513d5f823e3d90fd5b925050508161137d9293503d8411610356576103448183610f60565b949390929091505f61127a565b8b513d5f823e3d90fd5b61139f9299506110d9565b96885f6111ea565b601183634e487b7160e01b5f525260245ffd5b996111bd565b601184634e487b7160e01b5f525260245ffd5b509650505050915092935080519283019183831067ffffffffffffffff8411176114015750525f8152905f90565b604190634e487b7160e01b5f525260245ffd5b9881518a1015611447576114288a836110b1565b51156114475761144161143b8792610fcd565b9a610fcd565b90611189565b9861118e565b875163143ee5b960e01b81526001600160a01b0386168582019081526020810183905260a0919082908290819060400103818b5afa9182156114ed57908d92915f926114cc575b50506114aa575b506114a590610fcd565b611178565b82826114bd6114a594956114c3946110b1565b52610fcd565b9190508a61149b565b6114e29250803d10610356576103448183610f60565b505050505f80611494565b8a513d5f823e3d90fd5b90978682813d831161151f575b61150e8183610f60565b8101031261134d575051965f611149565b503d611504565b85513d5f823e3d90fd5b606460405162461bcd60e51b815260206004820152602060248201527f506167652073697a65206d7573742062652067726561746572207468616e20306044820152fd5b60405162461bcd60e51b815260206004820152602260248201527f50616765206e756d626572206d7573742062652067726561746572207468616e604482015261020360f41b6064820152608490fdfea26469706673582212206f898f816534106cbcb8062f454279cb0e0753fa590028aa359b3ab4dc3cf26d64736f6c634300081400330000000000000000000000006fabb568bb71041d92b4e541eb99eba3598c5a21
Deployed ByteCode
0x6080806040526004361015610012575f80fd5b60e05f35811c9182633c11abb414610d56575081633e6968b614610cd65781634844e11014610c5b57816351c1e94d146107fe5750806355ab7b45146105f15780638da5cb5b146105ca5780638e98465e14610498578063ad6f2efe14610470578063e6bfd81f146104385763e7b4a0731461008c575f80fd5b3461030f5761009a36610e81565b91908290606060206040516100ae81610f30565b5f815201526100be811515610f82565b60015460405163bf627bf560e01b81526001600160a01b039091169490602081600481895afa90811561031b575f91610406575b508091116103fe575b505f93815b83811115610377575061011285611062565b946040519561012087610f30565b818752602087015280610190575b50505050506040518091602082526020606083019180518285015201519060408084015281518091526020608084019201905f5b818110610170575050500390f35b9193509160206101836001928651610eab565b9401910191849392610162565b5f9592939495935b858111158061036e575b1561035d5760405163143ee5b960e01b81526001600160a01b03881660048201526024810182905260a081604481875afa801561031b575f915f80915f93610326575b50836101fe575b505050506101f990610fcd565b610198565b846102118a60208b9c97989c01516110b1565b5152602061022285828b01516110b1565b510152604051638f10aca760e01b81526001600160a01b038b166004820152602481018990526020816044818a5afa90811561031b575f916102db575b50906101f994849392604061027b6102d19760208d01516110b1565b510152606061028e8560208c01516110b1565b51015260806102a18460208b01516110b1565b51015260a06102b48360208a01516110b1565b510152600160c06102c98360208a01516110b1565b510152610fcd565b94905f80806101ec565b93929190506020843d602011610313575b816102f960209383610f60565b8101031261030f579251919290916101f961025f565b5f80fd5b3d91506102ec565b6040513d5f823e3d90fd5b9250505061034c915060a03d60a011610356575b6103448183610f60565b810190610fdb565b915090915f6101e5565b503d61033a565b505050925050505f8080808061012e565b508185106101a2565b60405163143ee5b960e01b81526001600160a01b03861660048201526024810182905260a0908181604481875afa91821561031b575f926103dd575b50506103c8575b6103c390610fcd565b610100565b946103d56103c391610fcd565b9590506103ba565b6103f39250803d10610356576103448183610f60565b505050505f806103b3565b91505f6100fb565b90506020813d602011610430575b8161042160209383610f60565b8101031261030f57515f6100f2565b3d9150610414565b3461030f5761046661045261044c36610e81565b91611100565b604051928392604084526040840190610ef4565b9060208301520390f35b3461030f575f36600319011261030f576001546040516001600160a01b039091168152602090f35b3461030f575f36600319011261030f57600154604051634bd9351b60e01b81526001600160a01b039091169060208082600481865afa91821561031b575f9261059b575b506040516301999f8b60e31b8152928184600481845afa93841561031b575f9461056c575b5092816004946040519586809263bf627bf560e01b82525afa91821561031b575f9261053c575b606094506040519384528301526040820152f35b80925084813d8311610565575b6105538183610f60565b8101031261030f576060935191610528565b503d610549565b93508184813d8311610594575b6105838183610f60565b8101031261030f5792519281610501565b503d610579565b9080925081813d83116105c3575b6105b38183610f60565b8101031261030f575190836104dc565b503d6105a9565b3461030f575f36600319011261030f575f546040516001600160a01b039091168152602090f35b3461030f57604036600319011261030f5761060a610e6b565b602480359067ffffffffffffffff80831161030f573660238401121561030f57826004013590811161030f57600591368183851b8601011161030f57610651829392611062565b60015490946001600160a01b03909116925f5b85811061068557604051602080825281906106819082018a610ef4565b0390f35b60405163143ee5b960e01b81526001600160a01b038916600482015281831b840185013560248201819052919060a080826044818b5afa801561031b575f915f93858d5f925f956107c7575b5081818a6106e460809561070c956110b1565b5152602098896106f484846110b1565b51015287606061070484846110b1565b5101526110b1565b510152610719858d6110b1565b51015215158060c061072b858d6110b1565b510152156107b457604051638f10aca760e01b81526001600160a01b038b166004820152602481019390935280836044818a5afa90811561031b575f91610784575b5061077f925060406102c9838b6110b1565b610664565b905082813d83116107ad575b61079a8183610f60565b8101031261030f5761077f91518a61076d565b503d610790565b5061077f91505f60406102c9838b6110b1565b90945061070c96506107eb91955060809250833d8511610356576103448183610f60565b92985092969195929391929190506106d1565b3461030f5761080c36610e81565b929091908361081c841515610f82565b60019260018060a01b038454169160405163bf627bf560e01b81526020978882600481885afa801561031b5788925f91610c26575b50806108639411610c1e575b506110d9565b91848301809311610c0a5761087b8397969597611002565b946108896040519687610f60565b838652601f1961089885611002565b015f5b818110610bed5750505f5b84811061093457505050505060405193838594850190808652845180925280604087019501935f905b8382106108dc5787870388f35b85518051885280840151888501526040808201519089015260608082015115159089015260808082015115159089015260a0808201519089015260c090810151908801528897509586019594820194908401906108cf565b61094281839a98999a6110e6565b6040805163262cffef60e11b81526001600160a01b0387166004820152602481018390529192919081604481885afa90811561031b575f905f92610bad575b508361098d848d6110b1565b51528b61099a848d6110b1565b510152604051635ccbff4160e11b815260048101849052602491908c8184818a5afa90811561031b578c85915f93610b7b575b506040916109da916110b1565b51015260606109e9848d6110b1565b51821515910152604051631585119960e01b8152600481018590528c8184818a5afa90811561031b578c85915f93610b3a575b50608091610a29916110b1565b510190151590528b6040518093633a52bedd60e01b825286600483015281895afa801561031b57838c8e945f93610b04575b5060a091610a68916110b1565b51015215610af157604051638f10aca760e01b81526001600160a01b0387166004820152602481019390935282604481875afa801561031b575f90610ac2575b610ab9925060c06102c9838c6110b1565b979695976108a6565b508982813d8311610aea575b610ad88183610f60565b8101031261030f57610ab99151610aa8565b503d610ace565b50610ab991505f60c06102c9838c6110b1565b949250505082813d8311610b33575b610b1d8183610f60565b8101031261030f5790518b9190838c60a0610a5b565b503d610b13565b925050508c81813d8311610b74575b610b538183610f60565b8101031261030f576080610a2985610b6b8f946110f3565b93915091610a1c565b503d610b49565b925050508c81813d8311610ba6575b610b948183610f60565b8101031261030f5751838c60406109cd565b503d610b8a565b9150506040813d604011610be5575b81610bc960409383610f60565b8101031261030f57610bde8b825192016110f3565b908c610981565b3d9150610bbc565b9780999798610bfa61101a565b82828c010152019897969861089b565b634e487b7160e01b5f52601160045260245ffd5b90508961085d565b8093508a8092503d8311610c54575b610c3f8183610f60565b8101031261030f579051879190610863610851565b503d610c35565b3461030f57602036600319011261030f57610c74610e6b565b5f546001600160a01b03919082163303610ca557166bffffffffffffffffffffffff60a01b60015416176001555f80f35b60405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606490fd5b3461030f575f36600319011261030f5760015460405163bf627bf560e01b815290602090829060049082906001600160a01b03165afa801561031b575f90610d24575b602090604051908152f35b506020813d8211610d4e575b81610d3d60209383610f60565b8101031261030f5760209051610d19565b3d9150610d30565b3461030f5760208060031936011261030f57610d70610e6b565b60015463bf627bf560e01b84526001600160a01b03168284600481845afa93841561031b575f94610e3c575b505f9160015b85811115610db557505050604051908152f35b60405163143ee5b960e01b81526001600160a01b03831660048201526024810182905260a0908181604481885afa91821561031b575f92610e1b575b5050610e06575b610e0190610fcd565b610da2565b92610e13610e0191610fcd565b939050610df8565b610e319250803d10610356576103448183610f60565b505050508780610df1565b9093508281813d8311610e64575b610e548183610f60565b8101031261030f57519284610d9c565b503d610e4a565b600435906001600160a01b038216820361030f57565b606090600319011261030f576004356001600160a01b038116810361030f57906024359060443590565b9060c060e092805183526020810151602084015260408101516040840152606081015160608401526080810151608084015260a081015160a08401520151151560c08201520190565b9081518082526020808093019301915f5b828110610f13575050505090565b9091929382610f256001928751610eab565b950193929101610f05565b6040810190811067ffffffffffffffff821117610f4c57604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610f4c57604052565b15610f8957565b606460405162461bcd60e51b815260206004820152602060248201527f537461727420646179206d7573742062652067726561746572207468616e20306044820152fd5b5f198114610c0a5760010190565b908160a091031261030f578051916020820151916040810151916080606083015192015190565b67ffffffffffffffff8111610f4c5760051b60200190565b6040519060e0820182811067ffffffffffffffff821117610f4c576040528160c05f918281528260208201528260408201528260608201528260808201528260a08201520152565b9061106c82611002565b6110796040519182610f60565b828152809261108a601f1991611002565b01905f5b82811061109a57505050565b6020906110a561101a565b8282850101520161108e565b80518210156110c55760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b91908203918211610c0a57565b91908201809211610c0a57565b5190811515820361030f57565b90929192831561157457801561153057600180546040805163bf627bf560e01b81529460209391926001600160a01b031690600485888281865afa978815611526575f986114f7575b5061115388611002565b976111608651998a610f60565b808952601f1961116f82611002565b0136888b01375f855b8281111561144d575050505f978489905b611414575b5088156113d35761119f888a6110e6565b5f1999908a81019081116113c0578990049b8c8111156113ba57508b995b8a01998a116113a757888a0299808b048a14901517156113a757808a916111e48b846110e6565b11611394575b50506111f588611062565b985f5b89811061120d57505050505050505050509190565b61122061121a82846110e6565b846110b1565b51885163143ee5b960e01b81526001600160a01b0387168682019081526020810183905260a09081908390819060400103818c5afa91821561138a5760c08f868f95916112be928f95966112f299975f8081928295611361575b508a61128688886110b1565b51528b61129388886110b1565b51015260606112a287876110b1565b51015260806112b186866110b1565b51015261070484846110b1565b5101528a51638f10aca760e01b81526001600160a01b03891688820190815260208101929092529283918291604090910190565b03818a5afa9081156113575790898d93925f9261131d575b506102c983611318956110b1565b6111f8565b809394508c8092503d8311611350575b6113378183610f60565b8101031261134d5750518b9190896102c961130a565b80fd5b503d61132d565b89513d5f823e3d90fd5b925050508161137d9293503d8411610356576103448183610f60565b949390929091505f61127a565b8b513d5f823e3d90fd5b61139f9299506110d9565b96885f6111ea565b601183634e487b7160e01b5f525260245ffd5b996111bd565b601184634e487b7160e01b5f525260245ffd5b509650505050915092935080519283019183831067ffffffffffffffff8411176114015750525f8152905f90565b604190634e487b7160e01b5f525260245ffd5b9881518a1015611447576114288a836110b1565b51156114475761144161143b8792610fcd565b9a610fcd565b90611189565b9861118e565b875163143ee5b960e01b81526001600160a01b0386168582019081526020810183905260a0919082908290819060400103818b5afa9182156114ed57908d92915f926114cc575b50506114aa575b506114a590610fcd565b611178565b82826114bd6114a594956114c3946110b1565b52610fcd565b9190508a61149b565b6114e29250803d10610356576103448183610f60565b505050505f80611494565b8a513d5f823e3d90fd5b90978682813d831161151f575b61150e8183610f60565b8101031261134d575051965f611149565b503d611504565b85513d5f823e3d90fd5b606460405162461bcd60e51b815260206004820152602060248201527f506167652073697a65206d7573742062652067726561746572207468616e20306044820152fd5b60405162461bcd60e51b815260206004820152602260248201527f50616765206e756d626572206d7573742062652067726561746572207468616e604482015261020360f41b6064820152608490fdfea26469706673582212206f898f816534106cbcb8062f454279cb0e0753fa590028aa359b3ab4dc3cf26d64736f6c63430008140033