컴파일러
0.8.26+commit.8a97fa7a
파일 1 / 18 : AccessControlUpgradeable.sol
pragma solidity ^0.8.20;
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
struct AccessControlStorage {
mapping(bytes32 role => RoleData) _roles;
}
bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;
function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
assembly {
$.slot := AccessControlStorageLocation
}
}
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function __AccessControl_init() internal onlyInitializing {
}
function __AccessControl_init_unchained() internal onlyInitializing {
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
return $._roles[role].hasRole[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
AccessControlStorage storage $ = _getAccessControlStorage();
return $._roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
AccessControlStorage storage $ = _getAccessControlStorage();
bytes32 previousAdminRole = getRoleAdmin(role);
$._roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (!hasRole(role, account)) {
$._roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (hasRole(role, account)) {
$._roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
파일 2 / 18 : Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
파일 3 / 18 : ContextUpgradeable.sol
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
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;
}
}
파일 4 / 18 : ERC165Upgradeable.sol
pragma solidity ^0.8.20;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
abstract contract ERC165Upgradeable is Initializable, IERC165 {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
파일 5 / 18 : FGenesis.sol
pragma solidity ^0.8.26;
import {Genesis} from "./Genesis.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./GenesisTypes.sol";
import "./GenesisLib.sol";
contract FGenesis is Initializable, AccessControlUpgradeable {
using GenesisLib for *;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant OPERATION_ROLE = keccak256("OPERATION_ROLE");
struct Params {
address virtualToken;
uint256 reserve;
uint256 maxContribution;
address feeAddr;
uint256 feeAmt;
uint256 duration;
bytes32 tbaSalt;
address tbaImpl;
uint32 votePeriod;
uint256 threshold;
address agentFactory;
uint256 agentTokenTotalSupply;
uint256 agentTokenLpSupply;
}
Params public params;
mapping(uint256 => address) public genesisContracts;
uint256 public genesisID;
event GenesisCreated(uint256 indexed id, address indexed addr);
bytes32 public constant BONDING_ROLE = keccak256("BONDING_ROLE");
constructor() {
_disableInitializers();
}
function initialize(Params memory p) external initializer {
__AccessControl_init();
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(ADMIN_ROLE, msg.sender);
_setParams(p);
}
function setParams(Params calldata p) external onlyRole(ADMIN_ROLE) {
_setParams(p);
}
function _setParams(Params memory p) internal {
require(
p.virtualToken != address(0) &&
p.feeAddr != address(0) &&
p.tbaImpl != address(0) &&
p.agentFactory != address(0),
"Invalid addr"
);
require(
p.reserve > 0 && p.maxContribution > 0 && p.feeAmt > 0,
"Invalid amt"
);
require(
p.duration > 0 &&
p.agentTokenTotalSupply > 0 &&
p.agentTokenLpSupply > 0 &&
p.agentTokenTotalSupply >= p.agentTokenLpSupply,
"Invalid amt"
);
params = p;
}
function createGenesis(
GenesisCreationParams memory gParams
) external returns (address) {
require(
IERC20(params.virtualToken).transferFrom(
msg.sender,
params.feeAddr,
params.feeAmt
),
"transfer createGenesis fee failed"
);
gParams.endTime = gParams.startTime + params.duration;
genesisID++;
address addr = GenesisLib.validateAndDeploy(
genesisID,
address(this),
gParams,
params.tbaSalt,
params.tbaImpl,
params.votePeriod,
params.threshold,
params.agentFactory,
params.virtualToken,
params.reserve,
params.maxContribution,
params.agentTokenTotalSupply,
params.agentTokenLpSupply
);
IAccessControl(params.agentFactory).grantRole(
BONDING_ROLE,
address(addr)
);
genesisContracts[genesisID] = addr;
emit GenesisCreated(genesisID, addr);
return addr;
}
function _getGenesis(uint256 id) internal view returns (Genesis) {
address addr = genesisContracts[id];
require(addr != address(0), "Not found");
return Genesis(addr);
}
function onGenesisSuccess(
uint256 id,
SuccessParams calldata p
) external onlyRole(OPERATION_ROLE) returns (address) {
return
_getGenesis(id).onGenesisSuccess(
p.refundAddresses,
p.refundAmounts,
p.distributeAddresses,
p.distributeAmounts,
p.creator
);
}
function onGenesisSuccessSalt(
uint256 id,
SuccessParams calldata p,
bytes32 salt
) external onlyRole(OPERATION_ROLE) returns (address) {
return
_getGenesis(id).onGenesisSuccessSalt(
p.refundAddresses,
p.refundAmounts,
p.distributeAddresses,
p.distributeAmounts,
p.creator,
salt
);
}
function onGenesisFailed(
uint256 id,
uint256[] calldata participantIndexes
) external onlyRole(OPERATION_ROLE) {
_getGenesis(id).onGenesisFailed(participantIndexes);
}
function withdrawLeftAssetsAfterFinalized(
uint256 id,
address to,
address token,
uint256 amount
) external onlyRole(ADMIN_ROLE) {
_getGenesis(id).withdrawLeftAssetsAfterFinalized(to, token, amount);
}
function resetTime(
uint256 id,
uint256 newStartTime,
uint256 newEndTime
) external onlyRole(OPERATION_ROLE) {
_getGenesis(id).resetTime(newStartTime, newEndTime);
}
function cancelGenesis(uint256 id) external onlyRole(OPERATION_ROLE) {
_getGenesis(id).cancelGenesis();
}
}
파일 6 / 18 : Genesis.sol
pragma solidity ^0.8.26;
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./FGenesis.sol";
import "../virtualPersona/IAgentFactoryV3.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./GenesisTypes.sol";
contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
using SafeERC20 for IERC20;
bytes32 public constant FACTORY_ROLE = keccak256("FACTORY_ROLE");
mapping(address => uint256) public mapAddrToVirtuals;
mapping(address => uint256) public claimableAgentTokens;
address[] public participants;
uint256 public refundUserCountForFailed;
uint256 public genesisId;
FGenesis public factory;
uint256 public startTime;
uint256 public endTime;
string public genesisName;
string public genesisTicker;
uint8[] public genesisCores;
bytes32 public tbaSalt;
address public tbaImplementation;
uint32 public daoVotingPeriod;
uint256 public daoThreshold;
address public agentFactoryAddress;
address public virtualTokenAddress;
uint256 public reserveAmount;
uint256 public maxContributionVirtualAmount;
uint256 public agentTokenTotalSupply;
uint256 public agentTokenLpSupply;
address public agentTokenAddress;
bool public isFailed;
bool public isCancelled;
event AssetsWithdrawn(
uint256 indexed genesisID,
address indexed to,
address token,
uint256 amount
);
event TimeReset(
uint256 oldStartTime,
uint256 oldEndTime,
uint256 newStartTime,
uint256 newEndTime
);
event GenesisCancelled(uint256 indexed genesisID);
event GenesisSucceeded(uint256 indexed genesisID);
event GenesisFailed(uint256 indexed genesisID);
event Participated(
uint256 indexed genesisID,
address indexed user,
uint256 point,
uint256 virtuals
);
event RefundClaimed(
uint256 indexed genesisID,
address indexed user,
uint256 amount
);
event AgentTokenClaimed(
uint256 indexed genesisID,
address indexed user,
uint256 amount
);
event VirtualsWithdrawn(
uint256 indexed genesisID,
address indexed to,
address token,
uint256 amount
);
string private constant ERR_NOT_STARTED = "Genesis not started yet";
string private constant ERR_ALREADY_STARTED = "Genesis already started";
string private constant ERR_NOT_ENDED = "Genesis not ended yet";
string private constant ERR_ALREADY_ENDED = "Genesis already ended";
string private constant ERR_ALREADY_FAILED = "Genesis already failed";
string private constant ERR_ALREADY_CANCELLED = "Genesis already cancelled";
string private constant ERR_START_TIME_FUTURE =
"Start time must be in the future";
string private constant ERR_END_AFTER_START =
"End time must be after start time";
string private constant ERR_TOKEN_LAUNCHED = "Agent token already launched";
string private constant ERR_TOKEN_NOT_LAUNCHED = "Agent token not launched";
modifier whenNotStarted() {
require(!isStarted(), ERR_ALREADY_STARTED);
_;
}
modifier whenStarted() {
require(isStarted(), ERR_NOT_STARTED);
_;
}
modifier whenNotEnded() {
require(!isEnded(), ERR_ALREADY_ENDED);
_;
}
modifier whenEnded() {
require(isEnded(), ERR_NOT_ENDED);
_;
}
modifier whenNotFailed() {
require(!isFailed, ERR_ALREADY_FAILED);
_;
}
modifier whenNotCancelled() {
require(!isCancelled, ERR_ALREADY_CANCELLED);
_;
}
modifier whenTokenNotLaunched() {
require(agentTokenAddress == address(0), ERR_TOKEN_LAUNCHED);
_;
}
modifier whenTokenLaunched() {
require(agentTokenAddress != address(0), ERR_TOKEN_NOT_LAUNCHED);
_;
}
modifier whenActive() {
require(isStarted(), ERR_NOT_STARTED);
require(!isEnded(), ERR_ALREADY_ENDED);
require(!isFailed, ERR_ALREADY_FAILED);
require(!isCancelled, ERR_ALREADY_CANCELLED);
_;
}
modifier whenFinalized() {
require(isEnded(), ERR_NOT_ENDED);
require(
isFailed || isCancelled || agentTokenAddress != address(0),
"Genesis not finalized yet"
);
_;
}
function _validateTime(uint256 _startTime, uint256 _endTime) internal view {
require(_startTime > block.timestamp, ERR_START_TIME_FUTURE);
require(_endTime > _startTime, ERR_END_AFTER_START);
}
function initialize(
GenesisInitParams calldata params
) external initializer {
__AccessControl_init();
require(params.genesisID > 0, "Invalid genesis ID");
require(params.factory != address(0), "Invalid factory address");
_validateTime(params.startTime, params.endTime);
require(bytes(params.genesisName).length > 0, "Invalid genesis name");
require(
bytes(params.genesisTicker).length > 0,
"Invalid genesis ticker"
);
require(params.genesisCores.length > 0, "Invalid genesis cores");
require(
params.tbaImplementation != address(0),
"Invalid TBA implementation address"
);
require(
params.agentFactoryAddress != address(0),
"Invalid agent factory address"
);
require(
params.virtualTokenAddress != address(0),
"Invalid virtual token address"
);
require(
params.reserveAmount > 0,
"Reserve amount must be greater than 0"
);
require(
params.maxContributionVirtualAmount > 0,
"Max contribution must be greater than 0"
);
require(
params.agentTokenTotalSupply > 0,
"Agent token total supply must be greater than 0"
);
require(
params.agentTokenLpSupply > 0,
"Agent token lp supply must be greater than 0"
);
require(
params.agentTokenTotalSupply >= params.agentTokenLpSupply,
"Agent token total supply must be greater than agent token lp supply"
);
genesisId = params.genesisID;
factory = FGenesis(params.factory);
startTime = params.startTime;
endTime = params.endTime;
genesisName = params.genesisName;
genesisTicker = params.genesisTicker;
genesisCores = params.genesisCores;
tbaSalt = params.tbaSalt;
tbaImplementation = params.tbaImplementation;
daoVotingPeriod = params.daoVotingPeriod;
daoThreshold = params.daoThreshold;
agentFactoryAddress = params.agentFactoryAddress;
virtualTokenAddress = params.virtualTokenAddress;
reserveAmount = params.reserveAmount;
maxContributionVirtualAmount = params.maxContributionVirtualAmount;
agentTokenTotalSupply = params.agentTokenTotalSupply;
agentTokenLpSupply = params.agentTokenLpSupply;
_grantRole(DEFAULT_ADMIN_ROLE, params.factory);
_grantRole(FACTORY_ROLE, params.factory);
}
function participate(
uint256 pointAmt,
uint256 virtualsAmt
) external nonReentrant whenActive {
require(pointAmt > 0, "Point amount must be greater than 0");
require(virtualsAmt > 0, "Virtuals must be greater than 0");
require(
virtualsAmt <= maxContributionVirtualAmount,
"Exceeds maximum virtuals per contribution"
);
if (mapAddrToVirtuals[msg.sender] == 0) {
participants.push(msg.sender);
}
mapAddrToVirtuals[msg.sender] += virtualsAmt;
IERC20(virtualTokenAddress).safeTransferFrom(
msg.sender,
address(this),
virtualsAmt
);
emit Participated(genesisId, msg.sender, pointAmt, virtualsAmt);
}
function onGenesisSuccess(
address[] calldata refundVirtualsTokenUserAddresses,
uint256[] calldata refundVirtualsTokenUserAmounts,
address[] calldata distributeAgentTokenUserAddresses,
uint256[] calldata distributeAgentTokenUserAmounts,
address creator
)
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenNotCancelled
whenEnded
returns (address)
{
return
_onGenesisSuccessSalt(
refundVirtualsTokenUserAddresses,
refundVirtualsTokenUserAmounts,
distributeAgentTokenUserAddresses,
distributeAgentTokenUserAmounts,
creator,
keccak256(abi.encodePacked(msg.sender, block.timestamp))
);
}
function onGenesisSuccessSalt(
address[] calldata refundVirtualsTokenUserAddresses,
uint256[] calldata refundVirtualsTokenUserAmounts,
address[] calldata distributeAgentTokenUserAddresses,
uint256[] calldata distributeAgentTokenUserAmounts,
address creator,
bytes32 salt
)
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenNotCancelled
whenEnded
returns (address)
{
return _onGenesisSuccessSalt(
refundVirtualsTokenUserAddresses,
refundVirtualsTokenUserAmounts,
distributeAgentTokenUserAddresses,
distributeAgentTokenUserAmounts,
creator,
salt
);
}
function _onGenesisSuccessSalt(
address[] calldata refundVirtualsTokenUserAddresses,
uint256[] calldata refundVirtualsTokenUserAmounts,
address[] calldata distributeAgentTokenUserAddresses,
uint256[] calldata distributeAgentTokenUserAmounts,
address creator,
bytes32 salt
) internal returns (address) {
require(
refundUserCountForFailed == 0,
"OnGenesisFailed already called"
);
uint256 totalRefundAmount = 0;
for (uint256 i = 0; i < refundVirtualsTokenUserAmounts.length; i++) {
require(
mapAddrToVirtuals[refundVirtualsTokenUserAddresses[i]] >=
refundVirtualsTokenUserAmounts[i],
"Insufficient Virtual Token committed"
);
totalRefundAmount += refundVirtualsTokenUserAmounts[i];
}
bool isFirstLaunch = agentTokenAddress == address(0);
if (isFirstLaunch) {
IERC20(virtualTokenAddress).approve(
agentFactoryAddress,
reserveAmount
);
uint256 id = IAgentFactoryV3(agentFactoryAddress)
.initFromBondingCurve(
string.concat(genesisName, " by Virtuals"),
genesisTicker,
genesisCores,
tbaSalt,
tbaImplementation,
daoVotingPeriod,
daoThreshold,
reserveAmount,
creator
);
address agentToken = IAgentFactoryV3(agentFactoryAddress)
.executeBondingCurveApplicationSalt(
id,
agentTokenTotalSupply,
agentTokenLpSupply,
address(this),
salt
);
require(agentToken != address(0), "Agent token creation failed");
agentTokenAddress = agentToken;
}
uint256 totalDistributionAmount = 0;
for (uint256 i = 0; i < distributeAgentTokenUserAmounts.length; i++) {
totalDistributionAmount += distributeAgentTokenUserAmounts[i];
}
require(
IERC20(agentTokenAddress).balanceOf(address(this)) >=
totalDistributionAmount,
"Insufficient Agent Token balance"
);
for (uint256 i = 0; i < refundVirtualsTokenUserAddresses.length; i++) {
mapAddrToVirtuals[
refundVirtualsTokenUserAddresses[i]
] -= refundVirtualsTokenUserAmounts[i];
IERC20(virtualTokenAddress).safeTransfer(
refundVirtualsTokenUserAddresses[i],
refundVirtualsTokenUserAmounts[i]
);
emit RefundClaimed(
genesisId,
refundVirtualsTokenUserAddresses[i],
refundVirtualsTokenUserAmounts[i]
);
}
for (uint256 i = 0; i < distributeAgentTokenUserAddresses.length; i++) {
claimableAgentTokens[
distributeAgentTokenUserAddresses[i]
] = distributeAgentTokenUserAmounts[i];
}
emit GenesisSucceeded(genesisId);
return agentTokenAddress;
}
function claimAgentToken(address userAddress) external nonReentrant {
uint256 amount = claimableAgentTokens[userAddress];
require(amount > 0, "No tokens to claim");
claimableAgentTokens[userAddress] = 0;
IERC20(agentTokenAddress).safeTransfer(userAddress, amount);
emit AgentTokenClaimed(genesisId, userAddress, amount);
}
function getClaimableAgentToken(
address userAddress
) external view returns (uint256) {
return claimableAgentTokens[userAddress];
}
function onGenesisFailed(
uint256[] calldata participantIndexes
)
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenNotCancelled
whenNotFailed
whenTokenNotLaunched
whenEnded
{
for (uint256 i = 0; i < participantIndexes.length; i++) {
require(
participantIndexes[i] < participants.length,
"Index out of bounds"
);
address participant = participants[participantIndexes[i]];
uint256 virtualsAmt = mapAddrToVirtuals[participant];
if (virtualsAmt > 0) {
refundUserCountForFailed++;
mapAddrToVirtuals[participant] = 0;
IERC20(virtualTokenAddress).safeTransfer(
participant,
virtualsAmt
);
emit RefundClaimed(genesisId, participant, virtualsAmt);
}
}
if (refundUserCountForFailed == participants.length) {
isFailed = true;
emit GenesisFailed(genesisId);
}
}
function isEnded() public view returns (bool) {
return block.timestamp >= endTime;
}
function isStarted() public view returns (bool) {
return block.timestamp >= startTime;
}
function getParticipantCount() external view returns (uint256) {
return participants.length;
}
function getParticipantsPaginated(
uint256 startIndex,
uint256 pageSize
) external view returns (address[] memory) {
require(startIndex < participants.length, "Start index out of bounds");
uint256 actualPageSize = pageSize;
if (startIndex + pageSize > participants.length) {
actualPageSize = participants.length - startIndex;
}
address[] memory page = new address[](actualPageSize);
for (uint256 i = 0; i < actualPageSize; i++) {
page[i] = participants[startIndex + i];
}
return page;
}
struct ParticipantInfo {
address userAddress;
uint256 virtuals;
}
function getParticipantsInfo(
uint256[] calldata participantIndexes
) external view returns (ParticipantInfo[] memory) {
uint256 length = participantIndexes.length;
ParticipantInfo[] memory result = new ParticipantInfo[](length);
for (uint256 i = 0; i < length; i++) {
require(
participantIndexes[i] < participants.length,
"Index out of bounds"
);
address userAddress = participants[participantIndexes[i]];
result[i] = ParticipantInfo({
userAddress: userAddress,
virtuals: mapAddrToVirtuals[userAddress]
});
}
return result;
}
struct GenesisInfo {
uint256 genesisId;
address factory;
uint256 startTime;
uint256 endTime;
string genesisName;
string genesisTicker;
uint8[] genesisCores;
bytes32 tbaSalt;
address tbaImplementation;
uint32 daoVotingPeriod;
uint256 daoThreshold;
address agentFactoryAddress;
address virtualTokenAddress;
uint256 reserveAmount;
uint256 maxContributionVirtualAmount;
uint256 agentTokenTotalSupply;
uint256 agentTokenLpSupply;
address agentTokenAddress;
bool isFailed;
bool isCancelled;
}
function getGenesisInfo() public view returns (GenesisInfo memory) {
return
GenesisInfo({
genesisId: genesisId,
factory: address(factory),
startTime: startTime,
endTime: endTime,
genesisName: genesisName,
genesisTicker: genesisTicker,
genesisCores: genesisCores,
tbaSalt: tbaSalt,
tbaImplementation: tbaImplementation,
daoVotingPeriod: daoVotingPeriod,
daoThreshold: daoThreshold,
agentFactoryAddress: agentFactoryAddress,
virtualTokenAddress: virtualTokenAddress,
reserveAmount: reserveAmount,
maxContributionVirtualAmount: maxContributionVirtualAmount,
agentTokenTotalSupply: agentTokenTotalSupply,
agentTokenLpSupply: agentTokenLpSupply,
agentTokenAddress: agentTokenAddress,
isFailed: isFailed,
isCancelled: isCancelled
});
}
function withdrawLeftAssetsAfterFinalized(
address to,
address token,
uint256 amount
)
external
onlyRole(DEFAULT_ADMIN_ROLE)
nonReentrant
whenEnded
{
require(token != address(0), "Invalid token address");
require(
amount <= IERC20(token).balanceOf(address(this)),
"Insufficient balance to withdraw"
);
IERC20(token).safeTransfer(to, amount);
emit AssetsWithdrawn(genesisId, to, token, amount);
}
function resetTime(
uint256 newStartTime,
uint256 newEndTime
)
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenNotCancelled
whenNotFailed
whenNotStarted
whenNotEnded
{
_validateTime(newStartTime, newEndTime);
uint256 oldStartTime = startTime;
uint256 oldEndTime = endTime;
startTime = newStartTime;
endTime = newEndTime;
emit TimeReset(oldStartTime, oldEndTime, newStartTime, newEndTime);
}
function cancelGenesis()
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenNotCancelled
whenNotFailed
whenNotStarted
whenNotEnded
{
isCancelled = true;
emit GenesisCancelled(genesisId);
}
}
파일 7 / 18 : GenesisLib.sol
pragma solidity ^0.8.26;
import {Genesis} from "./Genesis.sol";
import "./GenesisTypes.sol";
library GenesisLib {
function validateAndDeploy(
uint256 genesisID,
address factory,
GenesisCreationParams memory params,
bytes32 tbaSalt,
address tbaImpl,
uint32 daoVotingPeriod,
uint256 daoThreshold,
address agentFactoryAddress,
address virtualToken,
uint256 reserve,
uint256 maxContribution,
uint256 agentTokenTotalSupply,
uint256 agentTokenLpSupply
) internal returns (address) {
require(
bytes(params.genesisName).length > 0 &&
bytes(params.genesisTicker).length > 0 &&
params.genesisCores.length > 0,
"Invalid params"
);
Genesis newGenesis = new Genesis();
GenesisInitParams memory initParams = GenesisInitParams({
genesisID: genesisID,
factory: factory,
startTime: params.startTime,
endTime: params.endTime,
genesisName: params.genesisName,
genesisTicker: params.genesisTicker,
genesisCores: params.genesisCores,
tbaSalt: tbaSalt,
tbaImplementation: tbaImpl,
daoVotingPeriod: daoVotingPeriod,
daoThreshold: daoThreshold,
agentFactoryAddress: agentFactoryAddress,
virtualTokenAddress: virtualToken,
reserveAmount: reserve,
maxContributionVirtualAmount: maxContribution,
agentTokenTotalSupply: agentTokenTotalSupply,
agentTokenLpSupply: agentTokenLpSupply
});
newGenesis.initialize(initParams);
return address(newGenesis);
}
}
파일 8 / 18 : GenesisTypes.sol
pragma solidity ^0.8.26;
struct GenesisCreationParams {
uint256 startTime;
uint256 endTime;
string genesisName;
string genesisTicker;
uint8[] genesisCores;
}
struct SuccessParams {
address[] refundAddresses;
uint256[] refundAmounts;
address[] distributeAddresses;
uint256[] distributeAmounts;
address creator;
}
struct GenesisInitParams {
uint256 genesisID;
address factory;
uint256 startTime;
uint256 endTime;
string genesisName;
string genesisTicker;
uint8[] genesisCores;
bytes32 tbaSalt;
address tbaImplementation;
uint32 daoVotingPeriod;
uint256 daoThreshold;
address agentFactoryAddress;
address virtualTokenAddress;
uint256 reserveAmount;
uint256 maxContributionVirtualAmount;
uint256 agentTokenTotalSupply;
uint256 agentTokenLpSupply;
}
파일 9 / 18 : IAccessControl.sol
pragma solidity ^0.8.20;
interface IAccessControl {
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
error AccessControlBadConfirmation();
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address callerConfirmation) external;
}
파일 10 / 18 : IAgentFactoryV3.sol
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/governance/IGovernor.sol";
interface IAgentFactoryV3 {
function proposeAgent(
string memory name,
string memory symbol,
string memory tokenURI,
uint8[] memory cores,
bytes32 tbaSalt,
address tbaImplementation,
uint32 daoVotingPeriod,
uint256 daoThreshold
) external returns (uint256);
function withdraw(uint256 id) external;
function totalAgents() external view returns (uint256);
function initFromBondingCurve(
string memory name,
string memory symbol,
uint8[] memory cores,
bytes32 tbaSalt,
address tbaImplementation,
uint32 daoVotingPeriod,
uint256 daoThreshold,
uint256 applicationThreshold_,
address creator
) external returns (uint256);
function executeBondingCurveApplication(
uint256 id,
uint256 totalSupply,
uint256 lpSupply,
address vault
) external returns (address);
function executeBondingCurveApplicationSalt(
uint256 id,
uint256 totalSupply,
uint256 lpSupply,
address vault,
bytes32 salt
) external returns (address);
}
파일 11 / 18 : IERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";
파일 12 / 18 : IERC20.sol
pragma solidity ^0.8.20;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
파일 13 / 18 : IERC20Permit.sol
pragma solidity ^0.8.20;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
파일 14 / 18 : IERC6372.sol
pragma solidity ^0.8.20;
interface IERC6372 {
function clock() external view returns (uint48);
function CLOCK_MODE() external view returns (string memory);
}
파일 15 / 18 : IGovernor.sol
pragma solidity ^0.8.20;
import {IERC165} from "../interfaces/IERC165.sol";
import {IERC6372} from "../interfaces/IERC6372.sol";
interface IGovernor is IERC165, IERC6372 {
enum ProposalState {
Pending,
Active,
Canceled,
Defeated,
Succeeded,
Queued,
Expired,
Executed
}
error GovernorInvalidProposalLength(uint256 targets, uint256 calldatas, uint256 values);
error GovernorAlreadyCastVote(address voter);
error GovernorDisabledDeposit();
error GovernorOnlyProposer(address account);
error GovernorOnlyExecutor(address account);
error GovernorNonexistentProposal(uint256 proposalId);
error GovernorUnexpectedProposalState(uint256 proposalId, ProposalState current, bytes32 expectedStates);
error GovernorInvalidVotingPeriod(uint256 votingPeriod);
error GovernorInsufficientProposerVotes(address proposer, uint256 votes, uint256 threshold);
error GovernorRestrictedProposer(address proposer);
error GovernorInvalidVoteType();
error GovernorQueueNotImplemented();
error GovernorNotQueuedProposal(uint256 proposalId);
error GovernorAlreadyQueuedProposal(uint256 proposalId);
error GovernorInvalidSignature(address voter);
event ProposalCreated(
uint256 proposalId,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] calldatas,
uint256 voteStart,
uint256 voteEnd,
string description
);
event ProposalQueued(uint256 proposalId, uint256 etaSeconds);
event ProposalExecuted(uint256 proposalId);
event ProposalCanceled(uint256 proposalId);
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
event VoteCastWithParams(
address indexed voter,
uint256 proposalId,
uint8 support,
uint256 weight,
string reason,
bytes params
);
function name() external view returns (string memory);
function version() external view returns (string memory);
function COUNTING_MODE() external view returns (string memory);
function hashProposal(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external pure returns (uint256);
function state(uint256 proposalId) external view returns (ProposalState);
function proposalThreshold() external view returns (uint256);
function proposalSnapshot(uint256 proposalId) external view returns (uint256);
function proposalDeadline(uint256 proposalId) external view returns (uint256);
function proposalProposer(uint256 proposalId) external view returns (address);
function proposalEta(uint256 proposalId) external view returns (uint256);
function proposalNeedsQueuing(uint256 proposalId) external view returns (bool);
function votingDelay() external view returns (uint256);
function votingPeriod() external view returns (uint256);
function quorum(uint256 timepoint) external view returns (uint256);
function getVotes(address account, uint256 timepoint) external view returns (uint256);
function getVotesWithParams(
address account,
uint256 timepoint,
bytes memory params
) external view returns (uint256);
function hasVoted(uint256 proposalId, address account) external view returns (bool);
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
string memory description
) external returns (uint256 proposalId);
function queue(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external returns (uint256 proposalId);
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external payable returns (uint256 proposalId);
function cancel(
address[] memory targets,
uint256[] memory values,
bytes[] memory calldatas,
bytes32 descriptionHash
) external returns (uint256 proposalId);
function castVote(uint256 proposalId, uint8 support) external returns (uint256 balance);
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) external returns (uint256 balance);
function castVoteWithReasonAndParams(
uint256 proposalId,
uint8 support,
string calldata reason,
bytes memory params
) external returns (uint256 balance);
function castVoteBySig(
uint256 proposalId,
uint8 support,
address voter,
bytes memory signature
) external returns (uint256 balance);
function castVoteWithReasonAndParamsBySig(
uint256 proposalId,
uint8 support,
address voter,
string calldata reason,
bytes memory params,
bytes memory signature
) external returns (uint256 balance);
}
파일 16 / 18 : Initializable.sol
pragma solidity ^0.8.20;
abstract contract Initializable {
struct InitializableStorage {
uint64 _initialized;
bool _initializing;
}
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
error InvalidInitialization();
error NotInitializing();
event Initialized(uint64 version);
modifier initializer() {
InitializableStorage storage $ = _getInitializableStorage();
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
modifier reinitializer(uint64 version) {
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
modifier onlyInitializing() {
_checkInitializing();
_;
}
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
function _disableInitializers() internal virtual {
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}
파일 17 / 18 : ReentrancyGuard.sol
pragma solidity ^0.8.20;
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
_status = ENTERED;
}
function _nonReentrantAfter() private {
_status = NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
파일 18 / 18 : SafeERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
error SafeERC20FailedOperation(address token);
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
{
"compilationTarget": {
"contracts/genesis/Genesis.sol": "Genesis"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AgentTokenClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AssetsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"}],"name":"GenesisCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"}],"name":"GenesisFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"}],"name":"GenesisSucceeded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"point","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"virtuals","type":"uint256"}],"name":"Participated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RefundClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldStartTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldEndTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newStartTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newEndTime","type":"uint256"}],"name":"TimeReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"genesisID","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VirtualsWithdrawn","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentFactoryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentTokenLpSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"agentTokenTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelGenesis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"claimAgentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimableAgentTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoVotingPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract FGenesis","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"genesisCores","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisTicker","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getClaimableAgentToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGenesisInfo","outputs":[{"components":[{"internalType":"uint256","name":"genesisId","type":"uint256"},{"internalType":"address","name":"factory","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"genesisName","type":"string"},{"internalType":"string","name":"genesisTicker","type":"string"},{"internalType":"uint8[]","name":"genesisCores","type":"uint8[]"},{"internalType":"bytes32","name":"tbaSalt","type":"bytes32"},{"internalType":"address","name":"tbaImplementation","type":"address"},{"internalType":"uint32","name":"daoVotingPeriod","type":"uint32"},{"internalType":"uint256","name":"daoThreshold","type":"uint256"},{"internalType":"address","name":"agentFactoryAddress","type":"address"},{"internalType":"address","name":"virtualTokenAddress","type":"address"},{"internalType":"uint256","name":"reserveAmount","type":"uint256"},{"internalType":"uint256","name":"maxContributionVirtualAmount","type":"uint256"},{"internalType":"uint256","name":"agentTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"agentTokenLpSupply","type":"uint256"},{"internalType":"address","name":"agentTokenAddress","type":"address"},{"internalType":"bool","name":"isFailed","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"}],"internalType":"struct Genesis.GenesisInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getParticipantCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"participantIndexes","type":"uint256[]"}],"name":"getParticipantsInfo","outputs":[{"components":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"virtuals","type":"uint256"}],"internalType":"struct Genesis.ParticipantInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getParticipantsPaginated","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"genesisID","type":"uint256"},{"internalType":"address","name":"factory","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"genesisName","type":"string"},{"internalType":"string","name":"genesisTicker","type":"string"},{"internalType":"uint8[]","name":"genesisCores","type":"uint8[]"},{"internalType":"bytes32","name":"tbaSalt","type":"bytes32"},{"internalType":"address","name":"tbaImplementation","type":"address"},{"internalType":"uint32","name":"daoVotingPeriod","type":"uint32"},{"internalType":"uint256","name":"daoThreshold","type":"uint256"},{"internalType":"address","name":"agentFactoryAddress","type":"address"},{"internalType":"address","name":"virtualTokenAddress","type":"address"},{"internalType":"uint256","name":"reserveAmount","type":"uint256"},{"internalType":"uint256","name":"maxContributionVirtualAmount","type":"uint256"},{"internalType":"uint256","name":"agentTokenTotalSupply","type":"uint256"},{"internalType":"uint256","name":"agentTokenLpSupply","type":"uint256"}],"internalType":"struct GenesisInitParams","name":"params","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isCancelled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isEnded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFailed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mapAddrToVirtuals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxContributionVirtualAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"participantIndexes","type":"uint256[]"}],"name":"onGenesisFailed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"refundVirtualsTokenUserAddresses","type":"address[]"},{"internalType":"uint256[]","name":"refundVirtualsTokenUserAmounts","type":"uint256[]"},{"internalType":"address[]","name":"distributeAgentTokenUserAddresses","type":"address[]"},{"internalType":"uint256[]","name":"distributeAgentTokenUserAmounts","type":"uint256[]"},{"internalType":"address","name":"creator","type":"address"}],"name":"onGenesisSuccess","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"refundVirtualsTokenUserAddresses","type":"address[]"},{"internalType":"uint256[]","name":"refundVirtualsTokenUserAmounts","type":"uint256[]"},{"internalType":"address[]","name":"distributeAgentTokenUserAddresses","type":"address[]"},{"internalType":"uint256[]","name":"distributeAgentTokenUserAmounts","type":"uint256[]"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"onGenesisSuccessSalt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"participants","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointAmt","type":"uint256"},{"internalType":"uint256","name":"virtualsAmt","type":"uint256"}],"name":"participate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refundUserCountForFailed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newStartTime","type":"uint256"},{"internalType":"uint256","name":"newEndTime","type":"uint256"}],"name":"resetTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tbaImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tbaSalt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"virtualTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawLeftAssetsAfterFinalized","outputs":[],"stateMutability":"nonpayable","type":"function"}]