Compare commits

..

No commits in common. "a41cef0dfe247dca940075464f1a7a4dbc0d5a84" and "4193447068dc17df6712aca2891e6c55242055a7" have entirely different histories.

14 changed files with 40 additions and 264 deletions

View File

@ -72,18 +72,6 @@ RESERVE_MINT_RATE=
RESERVE_TOKEN_NAME=
RESERVE_TOKEN_SYMBOL=
## Name and symbol for the base token of the ghostDAO protocol
FATSO_TOKEN_NAME=
FATSO_TOKEN_SYMBOL=
## Name and symbol for the staking token of the ghostDAO protocol
STINKY_TOKEN_NAME=
STINKY_TOKEN_SYMBOL=
## Name and symbol for the bridging token of the ghostDAO protocol
GHOST_TOKEN_NAME=
GHOST_TOKEN_SYMBOL=
SEPOLIA_TEST_RPC_URL=
SEPOLIA_TEST_API_KEY=
SEPOLIA_TEST_ENDPOINT=

View File

@ -6,30 +6,6 @@ START=1
END=12
VERIFY_NEEDED="--verify"
usage() {
echo "Correct deployer script usage:"
echo -e "\t-s, --start - from which contract deployment should start."
echo -e "\t-e, --end - last contract deployment to be done."
echo -e "\t-n, --network - network name to be deployed on."
echo -e "\t-b, --blockscout - should try to use blockscout as verifier."
echo -e "\nAvailable network names: ${AVAILIABLE_NETWORKS[@]}"
echo -e "\nContract enumeration:"
echo "0) Reserve"
echo "1) Authority"
echo "2) Fatso"
echo "3) Stinky"
echo "4) Ghost"
echo "5) Staking"
echo "6) Treasury"
echo "7) BondDepository"
echo "8) StakingDistributor"
echo "9) BondingCalculator"
echo "10) AfterPartyFirst"
echo "11) AfterPartySecond"
echo "12) AfterPartyThird"
exit 1
}
while [[ $# -gt 0 ]];
do
case "${1}" in
@ -48,17 +24,6 @@ do
shift
shift
;;
-b|--blockscout)
VERIFY_NEEDED+=" --verifier blockscout"
shift
;;
-h|--help)
usage
;;
*)
echo -e "\nERROR: Unknown option provided\n"
usage
;;
esac
done

View File

@ -7,9 +7,9 @@ import "./interfaces/IFTSO.sol";
import "./types/GhostAccessControlled.sol";
contract Fatso is ERC20Permit, IFTSO, GhostAccessControlled {
constructor(address _authority, string memory name, string memory symbol)
ERC20(name, symbol)
ERC20Permit(name)
constructor(address _authority)
ERC20("Fatso", "FTSO")
ERC20Permit("Fatso")
GhostAccessControlled(IGhostAuthority(_authority))
{}

View File

@ -13,10 +13,7 @@ contract Ghost is IGHST, ERC20, ERC20Permit, ERC20Votes {
address public override stnk;
address private _initializer;
constructor(address _stnk, string memory name, string memory symbol)
ERC20(name, symbol)
ERC20Permit(name)
{
constructor(address _stnk) ERC20("Ghost", "GHST") ERC20Permit("Ghost") {
stnk = _stnk;
_initializer = msg.sender;
}

View File

@ -27,10 +27,7 @@ contract Stinky is ISTNK, ERC20Permit {
mapping(address => uint256) private _shares;
mapping(address => mapping(address => uint256)) private _allowedValue;
constructor(uint256 usedIndex, string memory name, string memory symbol)
ERC20(name, symbol)
ERC20Permit(name)
{
constructor(uint256 usedIndex) ERC20("Stinky", "STNK") ERC20Permit("Stinky") {
_initializer = msg.sender;
_internalIndex = usedIndex;
_totalSupply = INITIAL_SHARES_SUPPLY;

View File

@ -5,9 +5,7 @@ import "@openzeppelin-contracts/token/ERC20/extensions/ERC20Permit.sol";
contract Reserve is ERC20Permit {
address private immutable _owner;
uint256 public accumulatedDonation;
uint256 public conversionRate;
uint256 public donationRate;
error OnlyOwner();
constructor(
@ -20,11 +18,11 @@ contract Reserve is ERC20Permit {
}
fallback() external payable {
_mint(msg.sender, msg.value);
_innerMint(msg.sender, msg.value);
}
receive() external payable {
_mint(msg.sender, msg.value);
_innerMint(msg.sender, msg.value);
}
function changeRate(uint256 rate) external {
@ -32,42 +30,22 @@ contract Reserve is ERC20Permit {
conversionRate = rate;
}
function changeDonationRate(uint256 rate) external {
if (msg.sender != _owner) revert OnlyOwner();
donationRate = rate;
}
function withdraw(address payable receiver) external {
if (msg.sender != _owner) revert OnlyOwner();
uint256 accumulatedDonationCached = accumulatedDonation;
accumulatedDonation = 0;
(bool sent,) = receiver.call{ value: accumulatedDonationCached }("");
(bool sent,) = receiver.call{ value: address(this).balance }("");
require(sent, "Failed to send Ether");
}
function superMint(address account, uint256 value) external {
if (msg.sender != _owner) revert OnlyOwner();
_mint(account, value);
_innerMint(account, value);
}
function mint(address account) external payable {
uint256 donation = msg.value * donationRate / 1e5;
accumulatedDonation += donation;
_mint(account, msg.value * conversionRate);
_innerMint(account, msg.value);
}
function burn(uint256 amount) external {
_burn(msg.sender, amount);
uint256 valueDiff = address(this).balance - accumulatedDonation;
uint256 valueBack = amount * valueDiff / (amount + totalSupply());
(bool sent,) = msg.sender.call{ value: valueBack }("");
require(sent, "Failed to send Ether");
}
function estimateAmount(uint256 amount) external view returns (uint256) {
uint256 valueDiff = address(this).balance - accumulatedDonation;
return amount * valueDiff / totalSupply();
function _innerMint(address who, uint256 amount) internal {
_mint(who, amount * conversionRate);
}
}

View File

@ -16,9 +16,9 @@ contract GhostBondDepositoryTest is Test {
uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000;
uint256 public constant LARGE_APPROVAL = 100000000000000000000000000000000;
uint256 public constant INITIAL_INDEX = 10819917194513808e56;
uint48 public constant EPOCH_LENGTH = 2200;
uint48 public constant EPOCH_NUMBER = 1;
uint48 public constant EPOCH_END_TIME = 1337;
uint48 public constant EPOCH_LENGTH = 2200;
uint48 public constant EPOCH_NUMBER = 1;
uint48 public constant EPOCH_END_TIME = 1337;
uint256 public constant initialMint = 10000000000000000000000000;
uint256 public constant initialDeposit = 1000000000000000000000000;
@ -59,9 +59,9 @@ contract GhostBondDepositoryTest is Test {
vault
);
reserve = new ERC20Mock("Reserve Token", "RET");
ftso = new Fatso(address(authority), "Fatso", "FTSO");
stnk = new Stinky(INITIAL_INDEX, "Stinky", "STNK");
ghst = new Ghost(address(stnk), "Ghost", "GHST");
ftso = new Fatso(address(authority));
stnk = new Stinky(INITIAL_INDEX);
ghst = new Ghost(address(stnk));
staking = new GhostStaking(
address(ftso),
address(stnk),

View File

@ -47,9 +47,9 @@ contract StakingTest is Test {
policy,
vault
);
ftso = new Fatso(address(authority), "Fatso", "FTSO");
stnk = new Stinky(INITIAL_INDEX, "Stinky", "STNK");
ghst = new Ghost(address(stnk), "Ghost", "GHST");
ftso = new Fatso(address(authority));
stnk = new Stinky(INITIAL_INDEX);
ghst = new Ghost(address(stnk));
staking = new GhostStaking(
address(ftso),
address(stnk),

View File

@ -22,7 +22,7 @@ contract StakingDistributorTest is Test {
uint48 public constant EPOCH_LENGTH = 2200;
uint48 public constant EPOCH_NUMBER = 1;
uint48 public constant EPOCH_END_TIME = 1337;
uint256 public constant INITIAL_INDEX = 10819917194513808e56;
uint256 public constant amount = 69 * 1e18;
@ -47,9 +47,9 @@ contract StakingDistributorTest is Test {
owner
);
reserve = new ERC20Mock("Reserve Token", "RET");
ftso = new Fatso(address(authority), "Fatso", "FTSO");
stnk = new Stinky(INITIAL_INDEX, "Stinky", "STNK");
ghst = new Ghost(address(stnk), "Ghost", "GHST");
ftso = new Fatso(address(authority));
stnk = new Stinky(INITIAL_INDEX);
ghst = new Ghost(address(stnk));
staking = new GhostStaking(
address(ftso),
address(stnk),

View File

@ -20,9 +20,6 @@ contract FatsoTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferTe
uint256 constant amount = 69;
uint256 constant maxAmount = type(uint256).max;
string constant name = "Fatso Test Name";
string constant symbol = "FTSOTST";
function setUp() public {
authority = new GhostAuthority(
deployer,
@ -30,7 +27,7 @@ contract FatsoTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferTe
deployer,
vault
);
token = new Fatso(address(authority), name, symbol);
token = new Fatso(address(authority));
initializePermit(address(token), amount, maxAmount);
initializeAllowance(alice, bob, address(token), amount, maxAmount, amount);
initializeTransfer(alice, bob, address(token), amount, 0);
@ -51,8 +48,8 @@ contract FatsoTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferTe
}
function test_correctlyConstructsAnERC20() public view {
assertEq(token.name(), name);
assertEq(token.symbol(), symbol);
assertEq(token.name(), "Fatso");
assertEq(token.symbol(), "FTSO");
assertEq(token.decimals(), 9);
}

View File

@ -28,9 +28,6 @@ contract GhostTest is
uint256 constant amount = 69;
uint256 constant maxAmount = type(uint256).max;
string constant name = "Ghost Test Name";
string constant symbol = "GHSTTST";
Stinky stnk;
Ghost ghst;
GhostAuthority public authority;
@ -44,8 +41,8 @@ contract GhostTest is
initializer,
initializer
);
stnk = new Stinky(INITIAL_INDEX, "Stinky", "STNK");
ghst = new Ghost(address(stnk), name, symbol);
stnk = new Stinky(INITIAL_INDEX);
ghst = new Ghost(address(stnk));
staking = new GhostStaking(
address(0),
address(stnk),
@ -66,8 +63,8 @@ contract GhostTest is
}
function test_isConstructedCorrectly() public view {
assertEq(ghst.name(), name);
assertEq(ghst.symbol(), symbol);
assertEq(ghst.name(), "Ghost");
assertEq(ghst.symbol(), "GHST");
assertEq(ghst.decimals(), 18);
assertEq(ghst.staking(), address(staking));
assertEq(ghst.stnk(), address(stnk));

View File

@ -35,9 +35,6 @@ contract ReserveTest is Test {
assertEq(reserve.symbol(), symbol);
assertEq(reserve.decimals(), 18);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.conversionRate(), conversionRate);
}
function test_mint_couldBeDoneWithValue() public {
@ -75,7 +72,7 @@ contract ReserveTest is Test {
assertEq(reserve.balanceOf(initializer), 0);
vm.prank(initializer);
reserve.superMint(initializer, 420 * 1e18);
assertEq(reserve.balanceOf(initializer), 420 * 1e18);
assertEq(reserve.balanceOf(initializer), 420 * 1e18 * conversionRate);
}
function test_mint_superMintCouldNotBeDoneFromArbitraryAddress() public {
@ -86,37 +83,6 @@ contract ReserveTest is Test {
assertEq(reserve.balanceOf(aliceAddress), 0);
}
function test_mint_donationNotTakenIfRateNotSet() public {
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
}
function test_mint_donationIsTakenIfRateExists() public {
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.donationRate(), 0);
assertEq(reserve.accumulatedDonation(), 0);
vm.prank(initializer);
reserve.changeDonationRate(1e4); // 10%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.donationRate(), 1e4);
assertEq(reserve.accumulatedDonation(), sendAmount * 1e4 / 1e5);
}
function test_rate_couldBeChangedByDeployer() public {
assertEq(reserve.conversionRate(), conversionRate);
vm.prank(initializer);
@ -134,8 +100,6 @@ contract ReserveTest is Test {
function test_withdraw_couldBeDoneByDeployer() public {
assertEq(address(reserve).balance, 0);
vm.prank(initializer);
reserve.changeDonationRate(1e5);
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
@ -150,28 +114,6 @@ contract ReserveTest is Test {
assertEq(faucetAddress.balance, sendAmount);
}
function test_withdraw_onlyAccumulatedDonationsCouldBeWithdrawn() public {
assertEq(address(reserve).balance, 0);
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
assertEq(address(reserve).balance, sendAmount);
vm.prank(initializer);
reserve.withdraw(payable(faucetAddress));
assertEq(address(reserve).balance, sendAmount / 2);
assertEq(faucetAddress.balance, sendAmount / 2);
vm.prank(initializer);
reserve.withdraw(payable(faucetAddress));
assertEq(address(reserve).balance, sendAmount / 2);
assertEq(faucetAddress.balance, sendAmount / 2);
}
function test_withdraw_couldNotBeDoneByArbitraryAddress() public {
assertEq(address(reserve).balance, 0);
@ -188,86 +130,4 @@ contract ReserveTest is Test {
assertEq(address(reserve).balance, sendAmount);
assertEq(aliceAddress.balance, 0);
}
function test_burn_shouldReturnFullAmountIfRateNotSet() public {
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
uint256 balance = reserve.balanceOf(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.totalSupply(), balance);
assertEq(reserve.accumulatedDonation(), 0);
assertEq(aliceAddress.balance, 0);
vm.prank(aliceAddress);
reserve.burn(balance);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.balanceOf(aliceAddress), 0);
assertEq(reserve.accumulatedDonation(), 0);
assertEq(aliceAddress.balance, sendAmount);
}
function test_burn_shouldTakeDonationInAccordanceToRate() public {
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
uint256 balance = reserve.balanceOf(aliceAddress);
assertEq(reserve.totalSupply(), sendAmount * conversionRate);
assertEq(reserve.totalSupply(), balance);
assertEq(reserve.accumulatedDonation(), sendAmount / 2);
assertEq(aliceAddress.balance, 0);
vm.prank(aliceAddress);
reserve.burn(balance);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.balanceOf(aliceAddress), 0);
assertEq(reserve.accumulatedDonation(), sendAmount / 2);
assertEq(aliceAddress.balance, sendAmount / 2);
}
function test_burn_multipleUsersAccumulateInTotal() public {
vm.prank(initializer);
reserve.changeDonationRate(5 * 1e4); // 50%
deal(aliceAddress, sendAmount);
vm.prank(aliceAddress);
reserve.mint{ value: sendAmount }(aliceAddress);
vm.prank(initializer);
reserve.changeRate(conversionRate * 9);
deal(bobAddress, sendAmount);
vm.prank(bobAddress);
reserve.mint{ value: sendAmount }(bobAddress);
assertEq(aliceAddress.balance, 0);
assertEq(bobAddress.balance, 0);
uint256 aliceBalance = reserve.balanceOf(aliceAddress);
uint256 bobBalance = reserve.balanceOf(bobAddress);
uint256 bobEstimation = reserve.estimateAmount(bobBalance);
uint256 aliceEstimation = reserve.estimateAmount(aliceBalance);
vm.prank(bobAddress);
reserve.burn(bobBalance);
vm.prank(aliceAddress);
reserve.burn(aliceBalance);
assertEq(bobAddress.balance, sendAmount * 9 / 10);
assertEq(bobAddress.balance, bobEstimation);
assertEq(aliceAddress.balance, sendAmount / 10);
assertEq(aliceAddress.balance, aliceEstimation);
assertEq(reserve.totalSupply(), 0);
assertEq(reserve.accumulatedDonation(), sendAmount);
assertEq(address(reserve).balance, sendAmount);
}
}

View File

@ -35,9 +35,6 @@ contract StinkyTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferT
uint256 constant amount = 69;
uint256 constant maxAmount = type(uint256).max;
string constant name = "Stinky Test Name";
string constant symbol = "STNKTST";
event Transfer(address indexed from, address indexed to, uint256 value);
event LogStakingContractUpdated(address stakingContract);
@ -49,9 +46,9 @@ contract StinkyTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferT
initializer,
initializer
);
ftso = new Fatso(address(authority), "Fatso", "FTSO");
stnk = new Stinky(INITIAL_INDEX, name, symbol);
ghst = new Ghost(address(stnk), "Ghost", "GHST");
ftso = new Fatso(address(authority));
stnk = new Stinky(INITIAL_INDEX);
ghst = new Ghost(address(stnk));
staking = new GhostStaking(
address(ftso),
address(stnk),
@ -70,8 +67,8 @@ contract StinkyTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferT
}
function test_isConstructedCorrectly() public view {
assertEq(stnk.name(), name);
assertEq(stnk.symbol(), symbol);
assertEq(stnk.name(), "Stinky");
assertEq(stnk.symbol(), "STNK");
assertEq(stnk.decimals(), 9);
assertEq(stnk.totalSupply(), TOTAL_INITIAL_SUPPLY);
assertEq(stnk.index(), INITIAL_INDEX / (TOTAL_SHARES / INITIAL_SHARES_SUPPLY));
@ -249,7 +246,7 @@ contract StinkyTest is Test, ERC20PermitTest, ERC20AllowanceTest, ERC20TransferT
uint256 prevIndex = stnk.index();
_mintTokens(alice, amount);
assertEq(stnk.balanceOf(alice), amount);
vm.prank(address(staking));
stnk.rebase(0, epoch);

View File

@ -35,7 +35,7 @@ contract GhostTreasuryTest is Test {
);
reserve = new ERC20Mock("Reserve Token", "RET");
liquidity = new ERC20Mock("Liquidity Token", "LDT");
ftso = new Fatso(address(authority), "Fatso", "FTSO");
ftso = new Fatso(address(authority));
treasury = new GhostTreasury(address(ftso), 69, address(authority));
calculator = new GhostBondingCalculator(address(ftso));
vm.stopPrank();