Skip to content

Feat/increase genesis fdv #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 7 additions & 31 deletions contracts/genesis/FGenesis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,15 @@ contract FGenesis is Initializable, AccessControlUpgradeable {

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"
p.virtualToken != address(0) && p.feeAddr != address(0) &&
p.tbaImpl != address(0) && p.agentFactory != address(0),
"Zero 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,
p.reserve > 0 && p.maxContribution > 0 && p.feeAmt > 0 &&
p.duration > 0 && p.agentTokenTotalSupply > 0 &&
p.agentTokenLpSupply > 0 && p.agentTokenTotalSupply >= p.agentTokenLpSupply,
"Invalid amt"
);

Expand All @@ -82,14 +74,11 @@ contract FGenesis is Initializable, AccessControlUpgradeable {
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++;
Expand Down Expand Up @@ -125,19 +114,6 @@ contract FGenesis is Initializable, AccessControlUpgradeable {
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,
Expand Down
144 changes: 80 additions & 64 deletions contracts/genesis/Genesis.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
"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";
string private constant ERR_ZERO_ADD = "Address cannot be empty";
string private constant ERR_INVALID_PARAM = "Invalid value for parameter";

// Common validation modifiers
modifier whenNotStarted() {
Expand Down Expand Up @@ -159,6 +161,11 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
_;
}

uint256 public totalDonateAmt;
mapping(address => uint256) public mapAddrToDonateAmt;
address[] public donors;
event Donate(uint256 indexed genesisID, address indexed user, uint256 amount);

function _validateTime(uint256 _startTime, uint256 _endTime) internal view {
require(_startTime > block.timestamp, ERR_START_TIME_FUTURE);
require(_endTime > _startTime, ERR_END_AFTER_START);
Expand All @@ -169,46 +176,24 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
) external initializer {
__AccessControl_init();

require(params.genesisID > 0, "Invalid genesis ID");
require(params.factory != address(0), "Invalid factory address");
require(params.genesisID > 0, "Invalid ID");
require(params.factory != address(0) && params.tbaImplementation != address(0)
&& params.agentFactoryAddress != address(0) && params.virtualTokenAddress != address(0), ERR_ZERO_ADD);
_validateTime(params.startTime, params.endTime);
require(bytes(params.genesisName).length > 0, "Invalid genesis name");
require(bytes(params.genesisName).length > 0, "Invalid 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"
"Invalid ticker"
);
require(params.genesisCores.length > 0, "Invalid cores");
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"
params.reserveAmount > 0 && params.maxContributionVirtualAmount > 0
&& params.agentTokenTotalSupply > 0 && params.agentTokenLpSupply > 0,
ERR_INVALID_PARAM
);
require(
params.agentTokenTotalSupply >= params.agentTokenLpSupply,
"Agent token total supply must be greater than agent token lp supply"
"Agent token total supply must be > agent token lp supply"
);

genesisId = params.genesisID;
Expand Down Expand Up @@ -237,8 +222,8 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
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(pointAmt > 0, "Point amount must be > 0");
require(virtualsAmt > 0, "Virtuals must be > 0");

// Check single submission upper limit
require(
Expand All @@ -263,31 +248,6 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
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,
Expand Down Expand Up @@ -346,9 +306,11 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
// grant allowance to agentFactoryAddress for launch
IERC20(virtualTokenAddress).approve(
agentFactoryAddress,
reserveAmount
reserveAmount + totalDonateAmt
);

uint256 agentTokenLpSupplyAfterDonate = calAgentTokenLpSupplyAfterDonate(totalDonateAmt);

// Call initFromBondingCurve and executeBondingCurveApplication
uint256 id = IAgentFactoryV3(agentFactoryAddress)
.initFromBondingCurve(
Expand All @@ -359,20 +321,20 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
tbaImplementation,
daoVotingPeriod,
daoThreshold,
reserveAmount,
reserveAmount + totalDonateAmt,
creator
);

address agentToken = IAgentFactoryV3(agentFactoryAddress)
.executeBondingCurveApplicationSalt(
id,
agentTokenTotalSupply,
agentTokenLpSupply,
agentTokenLpSupplyAfterDonate,
address(this), // vault
salt
);

require(agentToken != address(0), "Agent token creation failed");
require(agentToken != address(0), ERR_ZERO_ADD);

// Store the created agent token address
agentTokenAddress = agentToken;
Expand Down Expand Up @@ -597,7 +559,7 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
whenEnded
whenFinalized
{
require(token != address(0), "Invalid token address");
require(token != address(0), ERR_ZERO_ADD);
require(
amount <= IERC20(token).balanceOf(address(this)),
"Insufficient balance to withdraw"
Expand Down Expand Up @@ -644,4 +606,58 @@ contract Genesis is ReentrancyGuard, AccessControlUpgradeable {
isCancelled = true;
emit GenesisCancelled(genesisId);
}

function donate(uint256 amount)
external nonReentrant whenActive
{
require(amount > 0, "invalid amount");
IERC20(virtualTokenAddress).transferFrom(msg.sender, address(this), amount);
totalDonateAmt += amount;
mapAddrToDonateAmt[msg.sender] += amount;
if (mapAddrToDonateAmt[msg.sender] == 0) {
donors.push(msg.sender);
}
emit Donate(genesisId, msg.sender, amount);

// maybe have a maxCap for the donateAmt
}

function withdrawAgentTokenFromDonate() external onlyRole(FACTORY_ROLE) {
if (totalDonateAmt > 0) {
uint256 agentTokenLpSupplyAfterDonate = calAgentTokenLpSupplyAfterDonate(totalDonateAmt);
uint256 agentTokenFromDonate = agentTokenLpSupply - agentTokenLpSupplyAfterDonate;
IERC20(agentTokenAddress).safeTransfer(msg.sender, agentTokenFromDonate);
}
}

function calAgentTokenLpSupplyAfterDonate(uint256 donateAmt) public view returns (uint256) {
uint256 numerator = 48000 * 125000000 * 1e18;
uint256 denominator = (48000 * 1e18 + donateAmt);
return numerator / denominator;
}

function refundDonate(
uint256[] calldata donorIndexes
)
external
onlyRole(FACTORY_ROLE)
nonReentrant
whenTokenNotLaunched
whenEnded
{
require(isFailed, "Genesis not failed");

for (uint256 i = 0; i < donorIndexes.length; i++) {
require(
donorIndexes[i] < donors.length,
"Index out of bounds"
);
address donor = donors[donorIndexes[i]];
uint256 donateAmt = mapAddrToDonateAmt[donor];
if (donateAmt > 0) {
IERC20(virtualTokenAddress).transfer(donor, donateAmt);
mapAddrToDonateAmt[donor] = 0;
}
}
}
}
19 changes: 19 additions & 0 deletions test/genesis/size.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Contract Size", function () {
it("Should be within size limits", async function () {
const Genesis = await ethers.getContractFactory("Genesis");
const FGenesis = await ethers.getContractFactory("FGenesis");

const genesisSize = Genesis.bytecode.length / 2;
const fGenesisSize = FGenesis.bytecode.length / 2;

console.log('Genesis size:', genesisSize, 'bytes');
console.log('FGenesis size:', fGenesisSize, 'bytes');

// 24576 是 EVM contract size limit
expect(genesisSize).to.be.lessThan(24576, "Genesis contract too large");
expect(fGenesisSize).to.be.lessThan(24576, "FGenesis contract too large");
});
});