Skip to content

Commit

Permalink
hardening, testing, v3 release
Browse files Browse the repository at this point in the history
  • Loading branch information
devinaconley committed Jul 10, 2023
1 parent 614dfff commit 7406793
Show file tree
Hide file tree
Showing 51 changed files with 3,612 additions and 271 deletions.
20 changes: 10 additions & 10 deletions .env.template
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
# .env

// infura ethereum API key
# infura ethereum API key
INFURA_KEY=

// etherscan api key
# etherscan api key
ETHERSCAN_KEY=

// ledger derivation path account index
# ledger derivation path account index
DEPLOYER_INDEX=

// address of GYSR token contract
# address of GYSR token contract
GYSR_ADDRESS=

// address of GYSR configuration contract
# address of GYSR configuration contract
CONFIG_ADDRESS=

// address of main pool factory
# address of main pool factory
FACTORY_ADDRESS=

// mnemonic phrase for temporary deployer
# mnemonic phrase for temporary deployer
MNEMONIC_PHRASE=

// polygonscan api key
# polygonscan api key
POLYGONSCAN_KEY=

// optimistic etherscan key
OPTIMISTIC_ETHERSCAN_KEY=
# optimistic etherscan key
OPTIMISTIC_ETHERSCAN_KEY=
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ truffle-config.js
abis/
artifacts/
cache/
stage/

coverage/
coverage.json
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020-2021 gysr-io
Copyright (c) 2020-2023 gysr-io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ npm install @gysr/core

See the [documentation](https://docs.gysr.io/developers) to learn more about interacting with the GYSR protocol.

*Note: the package is published with solidity `^0.8.18` compatibility, but core contracts have only been tested and audited with solidity `0.8.18` exact.*


## Development

Expand Down Expand Up @@ -46,7 +48,7 @@ npx hardhat compile && npx hardhat test --grep ERC20CompetitiveRewardModule
## Deploy

Copy `.env.template` to `.env` and define the `INFURA_KEY`, `DEPLOYER_INDEX`,
and `TREASURY_ADDRESS` variables.
and `ETHERSCAN_KEY` variables.


To deploy GYSR token to Goerli
Expand All @@ -57,6 +59,14 @@ npx hardhat run --network goerli scripts/i_deploy_token.js
Once GYSR token is deployed, define the `GYSR_ADDRESS` variable in your `.env` file.


To deploy the configuration contract to Goerli
```
npx hardhat run --network goerli scripts/i_deploy_config.js
```

Once the configuration contract is deployed, define the `CONFIG_ADDRESS` variable in your `.env` file.


To deploy the factory contract to Goerli
```
npx hardhat run --network goerli scripts/ii_deploy_factory.js
Expand All @@ -81,5 +91,5 @@ Follow the remaining migration steps to deploy all contracts and libraries.

To verify a contract on Goerli
```
npx hardhat verify --network goerli --contract contracts/PoolFactory.sol:PoolFactory 0xpoolfactory 0xgysrtoken 0xtreasury
npx hardhat verify --network goerli --contract contracts/PoolFactory.sol:PoolFactory 0xpoolfactory 0xgysrtoken 0xconfig
```
12 changes: 5 additions & 7 deletions contracts/ERC20BondStakingModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ contract ERC20BondStakingModule is IStakingModule, OwnerController, ERC721 {
}

// pricing
uint256 debt = (minted * 1e18) / (m.price + (m.coeff * m.debt) / 1e18);
uint256 debt = (minted * 1e18) / (m.price + (m.coeff * m.debt) / 1e24);
require(debt <= m.max, "bsm5");
require(debt <= capacity, "bsm6");
require(debt >= minimum, "bsm7");
require(debt > minimum, "bsm7");

// create new bond
uint256 id = nonce;
Expand Down Expand Up @@ -298,13 +298,10 @@ contract ERC20BondStakingModule is IStakingModule, OwnerController, ERC721 {
require(shares > 0, "bsm13");
uint256 bprincipal = b.principal;
uint256 bdebt = debt;
require(
shares < (bprincipal * (period - elapsed)) / period,
"bsm14"
); // strictly less than total unvested

// compute burned principal and debt shares
uint256 burned = (shares * period) / (period - elapsed);
require(burned < bprincipal, "bsm14"); // strictly less than total principal
debt = (bdebt * burned) / bprincipal;

// decrease bond position
Expand Down Expand Up @@ -404,7 +401,7 @@ contract ERC20BondStakingModule is IStakingModule, OwnerController, ERC721 {
* @notice open a new bond market
* @param token the principal token that will be deposited
* @param price minimum and starting price of the bond in tokens
* @param coeff bond pricing coefficient
* @param coeff bond pricing coefficient in price increase per debt shares (24 decimals)
* @param max maximum size for an individual bond in debt shares
* @param capacity the total debt available for this market in shares
*/
Expand Down Expand Up @@ -505,6 +502,7 @@ contract ERC20BondStakingModule is IStakingModule, OwnerController, ERC721 {

IERC20 tkn = IERC20(token);
uint256 shares = tkn.getShares(m.principal, amount);
require(shares > 0);
require(shares <= m.vested, "bsm31");

// withdraw
Expand Down
1 change: 1 addition & 0 deletions contracts/ERC20FixedRewardModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ contract ERC20FixedRewardModule is
require(amount > 0, "xrm6");
require(amount <= _token.balanceOf(address(this)), "xrm7");
uint256 shares = _token.getShares(rewards, amount);
require(shares > 0);
require(shares <= rewards - debt, "xrm8");

// withdraw
Expand Down
1 change: 1 addition & 0 deletions contracts/ERC20LinearRewardModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ contract ERC20LinearRewardModule is
require(amount > 0, "lrm5");
require(amount <= _token.balanceOf(address(this)), "lrm6");
uint256 shares = _token.getShares(rewardShares, amount);
require(shares > 0);
require(
(stakingShares * rate * period) / 1e18 + shares <
rewardShares - earned,
Expand Down
92 changes: 53 additions & 39 deletions contracts/ERC20MultiRewardModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {

/**
* @inheritdoc IRewardModule
*
* @dev stake and register for rewards on specified tokens
*
* `data`: address[] tokens
*/
function stake(
bytes32 account,
Expand Down Expand Up @@ -166,6 +170,10 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {

/**
* @inheritdoc IRewardModule
*
* @dev unstake and claim/unregister rewards on specified tokens
*
* `data`: address[] tokens (must be ordered)
*/
function unstake(
bytes32 account,
Expand All @@ -187,13 +195,9 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {
addr := calldataload(pos)
}
tkns[i] = addr;
// verify no duplicates
for (uint256 j; j < i; ) {
require(addr != tkns[j], "mrm7");
unchecked {
++j;
}
}
// verify ordered and no duplicates
if (i > 0) require(addr > tkns[i - 1], "mrm7");

// update token
_update(addr);
unchecked {
Expand Down Expand Up @@ -277,7 +281,10 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {
* @inheritdoc IRewardModule
*
* @dev claim rewards on specified tokens, optionally specify stakes, and optionally deregister
* @param data (bool continue, uint256 start, uint256 end, address[] tokens)
*
* `data`: (bool continue, uint256 start, uint256 end, address[] tokens)
*
* note: encoded token array addresses must be sorted
*/
function claim(
bytes32 account,
Expand Down Expand Up @@ -314,13 +321,9 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {
addr := calldataload(pos)
}
tkns[i] = addr;
// verify no duplicates
for (uint256 j; j < i; ) {
require(addr != tkns[j], "mrm14");
unchecked {
++j;
}
}
// verify ordered and no duplicates
if (i > 0) require(addr > tkns[i - 1], "mrm14");

// update token
_update(addr);
unchecked {
Expand Down Expand Up @@ -372,8 +375,11 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {
/**
* @inheritdoc IRewardModule
*
* @dev register for specified rewards token on existing stake
* @param (uint256 start, uint256 end, address[] tokens)
* @dev register or deregister for specified rewards token on existing stake
*
* `data`: (bool register, uint256 start, uint256 end, address[] tokens)
*
* note: encoded token array addresses must be sorted
*/
function update(
bytes32 account,
Expand All @@ -385,51 +391,59 @@ contract ERC20MultiRewardModule is ERC20BaseRewardModule {
if (data.length == 0) return; // empty data indicates skip

// validate
require(data.length > 64, "mrm15");
require(data.length > 96, "mrm15");
require(data.length % 32 == 0, "mrm16");
uint256 count = data.length / 32 - 2;
uint256 count = data.length / 32 - 3;
require(count <= _tokens.length, "mrm17");
// count > 0 implied by above

bool register; // register or deregister
uint256 index; // start claim index
uint256 end; // end of claim index range, exclusive
assembly {
index := calldataload(132)
end := calldataload(164)
register := calldataload(132)
index := calldataload(164)
end := calldataload(196)
}
require(index < end, "mrm18");
require(end <= stakes[account].length, "mrm19");

address prev;
for (uint256 i; i < count; ) {
uint256 pos = 196 + 32 * i;
uint256 pos = 228 + 32 * i;
address addr;
assembly {
addr := calldataload(pos)
}
// verify no duplicates
for (uint256 j; j < i; ) {
pos = 196 + 32 * j;
address prev;
assembly {
prev := calldataload(pos)
}
require(addr != prev, "mrm20");
unchecked {
++j;
}
}
// verify ordered and no duplicates
if (i > 0) require(addr > prev, "mrm20");

// update token
_update(addr);

for (uint256 j = index; j < end; ++j) {
if (stakes[account][j].registered[addr] > 0) continue;
stakes[account][j].count++;
stakes[account][j].registered[addr] = rewards[addr].accumulator;
rewards[addr].stakingShares += stakes[account][j].shares;
// register or clear accumulator
if (register) {
for (uint256 j = index; j < end; ++j) {
Stake storage s = stakes[account][j];
if (s.registered[addr] > 0) continue;
s.count++;
s.registered[addr] = rewards[addr].accumulator;
rewards[addr].stakingShares += s.shares;
}
} else {
for (uint256 j = index; j < end; ++j) {
Stake storage s = stakes[account][j];
if (s.registered[addr] == 0) continue;
_reward(s.shares, addr, s.registered[addr], 0); // renounce all rewards to dust
s.count--;
s.registered[addr] = 0;
rewards[addr].stakingShares -= s.shares;
}
}
unchecked {
++i;
}
prev = addr;
}

emit RewardsUpdated(account);
Expand Down
Loading

0 comments on commit 7406793

Please sign in to comment.