Skip to content
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

[WIP] develop --> main #152

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6159a15
fix: adding missing events in the treasury initialize function
0x3bfc May 22, 2022
735737f
Merge pull request #143 from aurora-is-near/fix/missing-events-in-tre…
0x3bfc May 23, 2022
05f8459
test: Stake/unstake in same block with dust rewards.
paouvrard May 25, 2022
512b0ee
Merge pull request #145 from aurora-is-near/pa/test-stake-unstake-sam…
0x3bfc May 25, 2022
4caad83
test: added more edge cases tests for stake-unstake in the same block
0x3bfc May 25, 2022
2d79674
minor cleanup
0x3bfc May 26, 2022
0cb6000
Merge pull request #146 from aurora-is-near/tests/more-unit-testing-f…
May 26, 2022
2134517
fix: (#140) add a minimum period of time between current timestamp an…
0x3bfc May 30, 2022
09fd534
fix: state variable `streamStartBuffer` naming
0x3bfc May 31, 2022
5424877
Merge pull request #150 from aurora-is-near/fix/min-period-of-time-be…
May 31, 2022
2305608
fix: (#153) validate `tau` parameter
0x3bfc May 31, 2022
32a6eb6
Merge branch 'develop' into fix/tau-validation
May 31, 2022
e043081
feat: Pause/unpause script.
paouvrard Jun 1, 2022
82f42de
update the shares and the rewards calculation documention
0x3bfc Jun 1, 2022
28fd1db
Merge pull request #154 from aurora-is-near/fix/tau-validation
Jun 2, 2022
8026166
fix: documentation in the `removeStream`
0x3bfc Jun 2, 2022
dc66774
Merge pull request #156 from aurora-is-near/fix/remove-stream-documen…
Jun 2, 2022
e32dc41
Merge pull request #155 from aurora-is-near/pa/pause-script
Jun 2, 2022
5beacf4
chore: slither annotations
vzctl Jul 5, 2022
8a37d8e
Merge branch 'main' into develop
Aug 2, 2022
1b72eb5
Update tests.yml
Sep 16, 2022
b29e50a
Merge pull request #171 from aurora-is-near/feat/deep-clean
Sep 16, 2022
3ff108e
chore(security): start using a shared workflow
vzctl Aug 1, 2022
f2e4d24
tests: Introduce foundry tests
lempire123 Jun 22, 2022
2aa1a19
tests(foundry): enable in the default workflow
vzctl Oct 20, 2022
a6d2793
Update tests.yml
vzctl Oct 20, 2022
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
Binary file removed .DS_Store
Binary file not shown.
24 changes: 7 additions & 17 deletions .github/workflows/static_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,12 @@ on:
- main
- develop
pull_request:
schedule:
- cron: "30 5 * * *"

name: jet-contracts
name: "Contract Security Analysis"
jobs:
tests:
name: Static Analysis (Check This Report Before Merging)
runs-on: [self-hosted, light]
env:
INFURA_KEY: ${{secrets.INFURA_KEY}}
ETHERSCAN_API_KEY: ${{secrets.ETHERSCAN_API_KEY}}
PRIVATE_KEY_TESTNET: ${{secrets.PRIVATE_KEY_TESTNET}}
PRIVATE_KEY: ${{secrets.PRIVATE_KEY}}
MNEMONIC: ${{secrets.MNEMONIC}}
AURORA_API_KEY: ${{secrets.AURORA_API_KEY}}
steps:
- name: Clone the repository
uses: actions/checkout@v2
- run: pip install slither-analyzer==0.8.2
- run: yarn install
- run: slither . --filter-paths "node_modules|testing" --exclude timestamp,reentrancy-no-eth,reentrancy-events,reentrancy-benign || true
contract_analysis:
name: "Security Check"
uses: aurora-is-near/.github/.github/workflows/contract_analysis.yml@master
secrets: inherit
6 changes: 6 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,11 @@ jobs:
uses: actions/checkout@v2
- run: yarn install --force
- run: yarn lint
- run: yarn deepClean
- run: yarn compile
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- run: yarn forge-test
- run: yarn coverage
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ artifacts/
# IDE
.DS_Store
# OpenZeppelin
.openzeppelin/
.openzeppelin/
# Foundry
out/
lib/
forge-cache/
#slither
slither/
1 change: 1 addition & 0 deletions contracts/AdminControlled.sol
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ contract AdminControlled is UUPSUpgradeable, AccessControlUpgradeable {
returns (bytes memory)
{
require(target != address(0), "ZERO_ADDRESS");
// slither-disable-next-line controlled-delegatecall,low-level-calls
(bool success, bytes memory rdata) = target.delegatecall(data);
require(success);
return rdata;
Expand Down
45 changes: 41 additions & 4 deletions contracts/JetStakingV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ contract JetStakingV1 is AdminControlled {
mapping(address => User) public users;
Stream[] streams;

uint256 streamStartBuffer;

// events
event Staked(address indexed user, uint256 amount, uint256 shares);

Expand Down Expand Up @@ -354,6 +356,8 @@ contract JetStakingV1 is AdminControlled {
stream.auroraDepositAmount = newAuroraDepositAmount;
// update stream reward schedules
_updateStreamRewardSchedules(streamId, rewardTokenAmount);
// TODO reorder the events
// slither-disable-next-line reentrancy-events
IERC20Upgradeable(auroraToken).safeTransfer(
stream.manager,
refundAuroraAmount
Expand Down Expand Up @@ -416,7 +420,9 @@ contract JetStakingV1 is AdminControlled {
? releaseAuroraAmount
: auroraTreasury // should not happen
);
// move the rest of rewards to the stream owner
// Move the rest of rewards to the stream fund receiver.
// Moving the rest of reward tokens to the stream owner
// will be handled outside of the scope of this contract.
ITreasury(treasury).payRewards(
streamFundReceiver,
stream.rewardToken,
Expand All @@ -435,6 +441,7 @@ contract JetStakingV1 is AdminControlled {
{
Stream storage stream = streams[streamId];
if (stream.status != StreamStatus.ACTIVE) return 0;
// slither-disable-next-line similar-names
uint256 scheduledReward = getRewardsAmount(
streamId,
stream.lastTimeOwnerClaimed
Expand Down Expand Up @@ -818,6 +825,7 @@ contract JetStakingV1 is AdminControlled {
returns (uint256)
{
require(lastUpdate <= block.timestamp, "INVALID_LAST_UPDATE");
// slither-disable-next-line incorrect-equality
if (lastUpdate == block.timestamp) return 0; // No more rewards since last update
uint256 streamStart = streams[streamId].schedule.time[0];
if (block.timestamp <= streamStart) return 0; // Stream didn't start
Expand Down Expand Up @@ -911,6 +919,7 @@ contract JetStakingV1 is AdminControlled {
/// @dev gets the total amount of staked aurora
/// @return totalAmountOfStakedAurora + latest reward schedule
function getTotalAmountOfStakedAurora() external view returns (uint256) {
// slither-disable-next-line incorrect-equality
if (touchedAt == 0) return 0;
return totalAmountOfStakedAurora + getRewardsAmount(0, touchedAt);
}
Expand Down Expand Up @@ -941,6 +950,7 @@ contract JetStakingV1 is AdminControlled {
}
}
// find end index
// slither-disable-next-line incorrect-equality
if (end == schedule.time[scheduleTimeLength - 1]) {
endIndex = scheduleTimeLength - 2;
} else {
Expand Down Expand Up @@ -1002,13 +1012,16 @@ contract JetStakingV1 is AdminControlled {
}

/// @dev called before touching the contract reserves (stake/unstake)
// slither-disable-next-line costly-loop
function _before() internal {
// slither-disable-next-line incorrect-equality
if (touchedAt == block.timestamp) return; // Already updated by previous tx in same block.
if (totalAuroraShares != 0) {
// Don't release rewards if there are no stakers.
totalAmountOfStakedAurora += getRewardsAmount(0, touchedAt);
uint256 streamsLength = streams.length;
for (uint256 i = 1; i < streamsLength; i++) {
// slither-disable-next-line incorrect-equality
if (streams[i].status == StreamStatus.ACTIVE) {
// If stream becomes blacklisted, no more rewards are released.
streams[i].rps = getLatestRewardPerShare(i);
Expand Down Expand Up @@ -1042,6 +1055,7 @@ contract JetStakingV1 is AdminControlled {
/// @param streamId the stream index
function _moveRewardsToPending(address account, uint256 streamId) internal {
require(streamId != 0, "AURORA_REWARDS_COMPOUND");
// slither-disable-next-line incorrect-equality
require(
streams[streamId].status == StreamStatus.ACTIVE,
"INACTIVE_OR_PROPOSED_STREAM"
Expand All @@ -1054,6 +1068,9 @@ contract JetStakingV1 is AdminControlled {
uint256 reward = ((streams[streamId].rps -
userAccount.rpsDuringLastClaim[streamId]) *
userAccount.streamShares) / RPS_MULTIPLIER;

// TODO replace with reward < 1 instead?
// slither-disable-next-line incorrect-equality
if (reward == 0) return; // All rewards claimed or stream schedule didn't start
userAccount.pendings[streamId] += reward;
userAccount.rpsDuringLastClaim[streamId] = streams[streamId].rps;
Expand All @@ -1070,6 +1087,7 @@ contract JetStakingV1 is AdminControlled {
function _moveAllRewardsToPending(address account) internal {
uint256 streamsLength = streams.length;
for (uint256 i = 1; i < streamsLength; i++) {
// slither-disable-next-line incorrect-equality
if (streams[i].status == StreamStatus.ACTIVE)
_moveRewardsToPending(account, i);
}
Expand All @@ -1083,6 +1101,7 @@ contract JetStakingV1 is AdminControlled {
internal
{
for (uint256 i = 0; i < streamIds.length; i++) {
// slither-disable-next-line incorrect-equality
if (streams[streamIds[i]].status == StreamStatus.ACTIVE)
_moveRewardsToPending(account, streamIds[i]);
}
Expand All @@ -1095,17 +1114,22 @@ contract JetStakingV1 is AdminControlled {
/// Unclaimed rewards will be lost.
/// `_before()` must be called before `_stake` to update streams rps
/// compounded AURORA rewards.
//slither-disable-next-line costly-loop
function _stake(address account, uint256 amount) internal {
// recalculation of shares for user
User storage userAccount = users[account];
uint256 _amountOfShares = 0;
// TODO change to be < 1 instead
// slither-disable-next-line incorrect-equality
if (totalAuroraShares == 0) {
// initialize the number of shares (_amountOfShares) owning 100% of the stake (amount)
_amountOfShares = amount;
} else {
// slither-disable-next-line divide-before-multiply
uint256 numerator = amount * totalAuroraShares;
_amountOfShares = numerator / totalAmountOfStakedAurora;
// check that rounding is needed (result * denominator < numerator).
// slither-disable-next-line divide-before-multiply
if (_amountOfShares * totalAmountOfStakedAurora < numerator) {
// Round up so users don't get less sharesValue than their staked amount
_amountOfShares += 1;
Expand Down Expand Up @@ -1187,15 +1211,15 @@ contract JetStakingV1 is AdminControlled {
);
// scheduleTimes[0] == proposal expiration time
require(
scheduleTimes[0] > block.timestamp,
"INVALID_STREAM_EXPIRATION_DATE"
scheduleTimes[0] > block.timestamp + streamStartBuffer,
"INVALID_STREAM_PROPOSAL_EXPIRATION_DATE"
);
require(
scheduleTimes.length == scheduleRewards.length,
"INVALID_SCHEDULE_VALUES"
);
require(scheduleTimes.length >= 2, "SCHEDULE_TOO_SHORT");
require(tau != 0, "INVALID_TAU_PERIOD");
require(tau != 0 && tau < ONE_MONTH, "INVALID_TAU_PERIOD");
for (uint256 i = 1; i < scheduleTimes.length; i++) {
require(
scheduleTimes[i] > scheduleTimes[i - 1],
Expand Down Expand Up @@ -1238,10 +1262,23 @@ contract JetStakingV1 is AdminControlled {
uint256 pendingAmount = userAccount.pendings[streamId];
userAccount.pendings[streamId] = 0;
emit Released(streamId, msg.sender, pendingAmount);
// slither-disable-next-line calls-loop
ITreasury(treasury).payRewards(
msg.sender,
streams[streamId].rewardToken,
pendingAmount
);
}

/// @dev update the minimum period of time between current timestamp and the start of schedule
/// called only stream manager role
/// @param _streamStartBuffer a minimum period value
// TODO fix visibility
// slither-disable-next-line external-function
function updateStreamStartBuffer(uint256 _streamStartBuffer)
public
onlyRole(STREAM_MANAGER_ROLE)
{
streamStartBuffer = _streamStartBuffer;
}
}
1 change: 1 addition & 0 deletions contracts/Treasury.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ contract Treasury is ITreasury, AdminControlled {
for (uint256 i = 0; i < _supportedTokens.length; i++) {
require(_supportedTokens[i] != address(0), "INVALID_TOKEN_ADDRESS");
isSupportedToken[_supportedTokens[i]] = true;
emit TokenAdded(_supportedTokens[i], msg.sender, block.timestamp);
}
__AdminControlled_init(_flags);
_grantRole(TREASURY_MANAGER_ROLE, msg.sender);
Expand Down
21 changes: 21 additions & 0 deletions deployments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,27 @@ yarn createStreamTRI:auroraMainnet
yarn createStreamBSTN:auroraMainnet
```

## Pausing contracts (Aurora Labs)

The default admin role can pause and unpause the contracts.
The pause role keys can only pause the contracts.

- Provide PRIVATE_KEY environment variable:
```bash
#.env file
PRIVATE_KEY= # Pause role or default admin.
```

- Review and execute the script in ./scripts/pause.js
```bash
yarn pause:auroraMainnet
```

- or execute `function adminPause(uint flags)` directly from MetaMask/Gnosis using the hex data:
```bash
0x2692c59f0000000000000000000000000000000000000000000000000000000000000001
```

## Verifying contracts

Proxy contracts were already automatically verified because of the automatic bytecode matching in [Aurorascan](https://aurorascan.dev), however to verify the implementation contracts, you have to use the `hardhat verify` as follows:
Expand Down
Loading