Skip to content

Commit

Permalink
Merge pull request #144 from moleculeprotocol/stefan/crowdsale-with-fees
Browse files Browse the repository at this point in the history
Fee taking crowdsale script fixes & additions
  • Loading branch information
elmariachi111 authored Oct 25, 2023
2 parents 888e838 + d0d560f commit d967ac0
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 201 deletions.
7 changes: 4 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ TERMS_ACCEPTED_PERMISSIONER_ADDRESS=0x610178dA211FEF7D417bC0e6FeD39F05609AD788

TOKENIZER_ADDRESS=0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0
STAKED_LOCKING_CROWDSALE_ADDRESS=0x9A676e781A523b5d0C0e43731313A708CB607508
CROWDSALE_WITH_FEES_ADDRESS=0x0B306BF915C4d645ff596e518fAf3F9669b97016

USDC6_ADDRESS=0x68B1D87F95878fE05B998F19b66F4baba5De1aed
WETH_ADDRESS=0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1
USDC6_ADDRESS=0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE
WETH_ADDRESS=0x59b670e9fA9D0A427751Af201D676719a970857b

PLAIN_CROWDSALE_ADDRESS=0x4A679253410272dd5232B3Ff7cF5dbB88f295319

#these are generated when running the fixture scripts
IPTS_ADDRESS=0x1F708C24a0D3A740cD47cC0444E9480899f3dA7D
Expand Down
2 changes: 1 addition & 1 deletion script/DeployTokenizer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ contract DeployTokenizerInfrastructure is Script {
);
tokenizer.initialize(IPNFT(ipnftAddress), p);

StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale(0);
StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale();

vm.stopBroadcast();

Expand Down
164 changes: 85 additions & 79 deletions script/dev/CrowdSale.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,152 +20,172 @@ import { IPToken } from "../../src/IPToken.sol";

import { CommonScript } from "./Common.sol";

contract DeployCrowdSale is CommonScript {
function run() public {
prepareAddresses();
vm.startBroadcast(deployer);
CrowdSale crowdSale = new CrowdSale();
crowdSale.setCurrentFeesBp(1000);

console.log("PLAIN_CROWDSALE_ADDRESS=%s", address(crowdSale));
}
}

/**
* @title deploy crowdSale
* @author
*/
contract DeployCrowdSale is CommonScript {
contract DeployStakedCrowdSale is CommonScript {
function run() public {
prepareAddresses();
vm.startBroadcast(deployer);
StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale(0);
CrowdSale crowdSaleWithFees = new CrowdSale(10);
StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale();

TokenVesting vestedDaoToken = TokenVesting(vm.envAddress("VDAO_TOKEN_ADDRESS"));
vestedDaoToken.grantRole(vestedDaoToken.ROLE_CREATE_SCHEDULE(), address(stakedLockingCrowdSale));
stakedLockingCrowdSale.trustVestingContract(vestedDaoToken);
vm.stopBroadcast();

//console.log("vested molecules Token %s", address(vestedMolToken));
console.log("STAKED_LOCKING_CROWDSALE_ADDRESS=%s", address(stakedLockingCrowdSale));
console.log("CROWDSALE_WITH_FEES_ADDRESS=%s", address(crowdSaleWithFees));
}
}

/**
* @notice execute Ipnft.s.sol && Fixture.s.sol && Tokenizer.s.sol first
* @notice assumes that bob (hh1) owns IPNFT#1 and has synthesized it
*/
contract FixtureCrowdSale is CommonScript {
FakeERC20 internal usdc;

FakeERC20 daoToken;
TokenVesting vestedDaoToken;

IPToken internal auctionToken;

StakedLockingCrowdSale stakedLockingCrowdSale;
CrowdSale crowdSaleWithFees;
CrowdSale crowdSale;
TermsAcceptedPermissioner permissioner;

function prepareAddresses() internal override {
function prepareAddresses() internal virtual override {
super.prepareAddresses();

usdc = FakeERC20(vm.envAddress("USDC_ADDRESS"));

daoToken = FakeERC20(vm.envAddress("DAO_TOKEN_ADDRESS"));
vestedDaoToken = TokenVesting(vm.envAddress("VDAO_TOKEN_ADDRESS"));
auctionToken = IPToken(vm.envAddress("IPTS_ADDRESS"));

stakedLockingCrowdSale = StakedLockingCrowdSale(vm.envAddress("STAKED_LOCKING_CROWDSALE_ADDRESS"));
crowdSaleWithFees = CrowdSale(vm.envAddress("CROWDSALE_WITH_FEES_ADDRESS"));
permissioner = TermsAcceptedPermissioner(vm.envAddress("TERMS_ACCEPTED_PERMISSIONER_ADDRESS"));
}

function setupVestedMolToken() internal {
vm.startBroadcast(deployer);
auctionToken = IPToken(vm.envAddress("IPTS_ADDRESS"));

vestedDaoToken.grantRole(vestedDaoToken.ROLE_CREATE_SCHEDULE(), address(stakedLockingCrowdSale));
vm.stopBroadcast();
crowdSale = CrowdSale(vm.envAddress("PLAIN_CROWDSALE_ADDRESS"));
permissioner = TermsAcceptedPermissioner(vm.envAddress("TERMS_ACCEPTED_PERMISSIONER_ADDRESS"));
}

function placeBid(address bidder, uint256 amount, uint256 saleId, bytes memory permission) internal {
vm.startBroadcast(bidder);
usdc.approve(address(stakedLockingCrowdSale), amount);
daoToken.approve(address(stakedLockingCrowdSale), amount);
stakedLockingCrowdSale.placeBid(saleId, amount, permission);
usdc.approve(address(crowdSale), amount);
daoToken.approve(address(crowdSale), amount);
crowdSale.placeBid(saleId, amount, permission);
vm.stopBroadcast();
}

function placeBidCrowdSaleWithFees(address bidder, uint256 amount, uint256 saleId, bytes memory permission) internal {
vm.startBroadcast(bidder);
usdc.approve(address(crowdSaleWithFees), amount);
daoToken.approve(address(crowdSaleWithFees), amount);
crowdSaleWithFees.placeBid(saleId, amount, permission);
vm.stopBroadcast();
}

function run() public virtual {
prepareAddresses();

setupVestedMolToken();

function prepareRun() internal virtual returns (Sale memory _sale) {
// Deal Charlie ERC20 tokens to bid in crowdsale
dealERC20(alice, 1200 ether, usdc);
dealERC20(charlie, 400 ether, usdc);

// Deal Alice and Charlie DAO tokens to stake in crowdsale
dealERC20(alice, 1200 ether, daoToken);
dealERC20(charlie, 400 ether, daoToken);

Sale memory _sale = Sale({
_sale = Sale({
auctionToken: IERC20Metadata(address(auctionToken)),
biddingToken: IERC20Metadata(address(usdc)),
beneficiary: bob,
fundingGoal: 200 ether,
salesAmount: 400 ether,
closingTime: uint64(block.timestamp + 15),
closingTime: uint64(block.timestamp + 10),
permissioner: permissioner
});

vm.startBroadcast(bob);
auctionToken.approve(address(crowdSale), 400 ether);
vm.stopBroadcast();
}

auctionToken.approve(address(stakedLockingCrowdSale), 400 ether);
auctionToken.approve(address(crowdSaleWithFees), 400 ether);
uint256 saleWithFeesId = crowdSaleWithFees.startSale(_sale);
uint256 saleId = stakedLockingCrowdSale.startSale(_sale, daoToken, vestedDaoToken, 1e18, 7 days);
TimelockedToken lockedIpt = stakedLockingCrowdSale.lockingContracts(address(auctionToken));
function startSale() internal virtual returns (uint256 saleId) {
Sale memory _sale = prepareRun();
vm.startBroadcast(bob);
saleId = crowdSale.startSale(_sale);
vm.stopBroadcast();
}

function afterRun(uint256 saleId) internal virtual {
console.log("SALE_ID=%s", saleId);
vm.writeFile("SALEID.txt", Strings.toString(saleId));
}

function run() public virtual {
prepareAddresses();

uint256 saleId = startSale();

string memory terms = permissioner.specificTermsV1(auctionToken);

(uint8 v, bytes32 r, bytes32 s) = vm.sign(alicePk, ECDSA.toEthSignedMessageHash(abi.encodePacked(terms)));
placeBid(alice, 600 ether, saleId, abi.encodePacked(r, s, v));
placeBidCrowdSaleWithFees(alice, 600 ether, saleWithFeesId, abi.encodePacked(r, s, v));
(v, r, s) = vm.sign(charliePk, ECDSA.toEthSignedMessageHash(abi.encodePacked(terms)));
placeBid(charlie, 200 ether, saleId, abi.encodePacked(r, s, v));

afterRun(saleId);
}
}
/**
* @notice execute Ipnft.s.sol && Fixture.s.sol && Tokenizer.s.sol first
* @notice assumes that bob (hh1) owns IPNFT#1 and has synthesized it
*/

contract FixtureStakedCrowdSale is FixtureCrowdSale {
StakedLockingCrowdSale _slCrowdSale;
TokenVesting vestedDaoToken;

function prepareAddresses() internal override {
super.prepareAddresses();
vestedDaoToken = TokenVesting(vm.envAddress("VDAO_TOKEN_ADDRESS"));

_slCrowdSale = StakedLockingCrowdSale(vm.envAddress("STAKED_LOCKING_CROWDSALE_ADDRESS"));
crowdSale = _slCrowdSale;
}

function prepareRun() internal virtual override returns (Sale memory _sale) {
_sale = super.prepareRun();
dealERC20(alice, 1200 ether, daoToken);
dealERC20(charlie, 400 ether, daoToken);
}

function startSale() internal override returns (uint256 saleId) {
Sale memory _sale = prepareRun();
vm.startBroadcast(bob);
saleId = _slCrowdSale.startSale(_sale, daoToken, vestedDaoToken, 1e18, 7 days);
vm.stopBroadcast();
}

function afterRun(uint256 saleId) internal virtual override {
super.afterRun(saleId);

TimelockedToken lockedIpt = _slCrowdSale.lockingContracts(address(auctionToken));
console.log("LOCKED_IPTS_ADDRESS=%s", address(lockedIpt));
console.log("SALE_ID=%s", saleId);
console.log("SALE_ID_WITH_FEES=%s", saleWithFeesId);
vm.writeFile("SALEWITHFEESID.txt", Strings.toString(saleWithFeesId));
vm.writeFile("SALEID.txt", Strings.toString(saleId));
}
}

contract ClaimSale is CommonScript {
function run() public {
prepareAddresses();
CrowdSale crowdSale = CrowdSale(vm.envAddress("CROWDSALE"));
TermsAcceptedPermissioner permissioner = TermsAcceptedPermissioner(vm.envAddress("TERMS_ACCEPTED_PERMISSIONER_ADDRESS"));
StakedLockingCrowdSale stakedLockingCrowdSale = StakedLockingCrowdSale(vm.envAddress("STAKED_LOCKING_CROWDSALE_ADDRESS"));
CrowdSale crowdSaleWithFees = CrowdSale(vm.envAddress("CROWDSALE_WITH_FEES_ADDRESS"));

IPToken auctionToken = IPToken(vm.envAddress("IPTS_ADDRESS"));
uint256 saleId = SLib.stringToUint(vm.readFile("SALEID.txt"));
uint256 saleWithFeesId = SLib.stringToUint(vm.readFile("SALEWITHFEESID.txt"));
vm.removeFile("SALEID.txt");
vm.removeFile("SALEWITHFEESID.txt");

vm.startBroadcast(anyone);
stakedLockingCrowdSale.settle(saleId);
crowdSaleWithFees.settle(saleWithFeesId);
stakedLockingCrowdSale.claimResults(saleId);
crowdSaleWithFees.claimResults(saleWithFeesId);
crowdSale.settle(saleId);
crowdSale.claimResults(saleId);
vm.stopBroadcast();

string memory terms = permissioner.specificTermsV1(auctionToken);

(uint8 v, bytes32 r, bytes32 s) = vm.sign(alicePk, ECDSA.toEthSignedMessageHash(abi.encodePacked(terms)));
vm.startBroadcast(alice);
stakedLockingCrowdSale.claim(saleId, abi.encodePacked(r, s, v));
crowdSale.claim(saleId, abi.encodePacked(r, s, v));
vm.stopBroadcast();

//we don't let charlie claim so we can test upgrades
Expand All @@ -175,17 +195,3 @@ contract ClaimSale is CommonScript {
// vm.stopBroadcast();
}
}

contract ClaimSaleWithFees is CommonScript {
function run() public {
prepareAddresses();
CrowdSale crowdSaleWithFees = CrowdSale(vm.envAddress("CROWDSALE_WITH_FEES_ADDRESS"));
uint256 saleId = SLib.stringToUint(vm.readFile("SALEID.txt"));
vm.removeFile("SALEID.txt");

vm.startBroadcast(anyone);
crowdSaleWithFees.settle(saleId);
crowdSaleWithFees.claimResults(saleId);
vm.stopBroadcast();
}
}
2 changes: 1 addition & 1 deletion script/prod/RolloutV23Sale.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract RolloutV23Sale is Script {
address moleculeDevMultisig = 0xCfA0F84660fB33bFd07C369E5491Ab02C449f71B;
vm.startBroadcast();

StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale(0);
StakedLockingCrowdSale stakedLockingCrowdSale = new StakedLockingCrowdSale();
stakedLockingCrowdSale.transferOwnership(moleculeDevMultisig);
vm.stopBroadcast();

Expand Down
16 changes: 11 additions & 5 deletions setupLocal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,26 @@ $FSC script/dev/Ipnft.s.sol:DeployIpnftSuite
$FSC script/dev/Tokens.s.sol:DeployTokens
$FSC script/dev/Periphery.s.sol
$FSC script/dev/Tokenizer.s.sol:DeployTokenizer
$FSC script/dev/CrowdSale.s.sol:DeployCrowdSale
$FSC script/dev/CrowdSale.s.sol:DeployStakedCrowdSale
$FSC script/dev/Tokens.s.sol:DeployFakeTokens
$FSC script/dev/CrowdSale.s.sol:DeployCrowdSale

# optionally: fixtures
if [ "$fixture" -eq "1" ]; then
echo "Running fixture scripts."

$FSC script/dev/Ipnft.s.sol:FixtureIpnft
$FSC script/dev/Tokenizer.s.sol:FixtureTokenizer
$FSC script/dev/CrowdSale.s.sol:FixtureCrowdSale
echo "Waiting 15 seconds until claiming sale..."

$FSC script/dev/CrowdSale.s.sol:FixtureCrowdSale
echo "Waiting 15 seconds until claiming plain sale..."
sleep 16
cast rpc evm_mine
CROWDSALE=$PLAIN_CROWDSALE_ADDRESS $FSC script/dev/CrowdSale.s.sol:ClaimSale

$FSC script/dev/CrowdSale.s.sol:ClaimSale
$FSC script/dev/CrowdSale.s.sol:FixtureStakedCrowdSale
echo "Waiting 15 seconds until claiming staked sale..."
sleep 16
cast rpc evm_mine
CROWDSALE=$STAKED_LOCKING_CROWDSALE_ADDRESS $FSC script/dev/CrowdSale.s.sol:ClaimSale
fi
Loading

0 comments on commit d967ac0

Please sign in to comment.