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

feat: unit improvements #13

Merged
merged 33 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b848147
feat: ownable contract and cooldownPeriod setter
gomesalexandre Apr 9, 2024
d51c10b
feat: unit improvements
gomesalexandre Apr 9, 2024
e666640
feat: all green
gomesalexandre Apr 9, 2024
be3480b
feat: more criteria to run CI
gomesalexandre Apr 9, 2024
b97fb56
feat: tmp ci monkey patch, revert me when confirmed happy
gomesalexandre Apr 9, 2024
78e9d24
feat: give an actual name to the action
gomesalexandre Apr 9, 2024
d9ee5b2
feat: bump foundry version in CI
gomesalexandre Apr 9, 2024
25ff298
chore: trigger CI
gomesalexandre Apr 9, 2024
b4d70f9
feat: remove monkey patch
gomesalexandre Apr 9, 2024
ca5d7a4
feat: coverage report in CI
gomesalexandre Apr 9, 2024
7c28a4c
feat: emit event including old address
gomesalexandre Apr 9, 2024
41093b6
feat: assume 43-bytes-length RUNE addy
gomesalexandre Apr 9, 2024
c43d486
feat: bring back CI monkey patch
gomesalexandre Apr 9, 2024
8f7d02c
feat: make it 100% again
gomesalexandre Apr 9, 2024
bfa67d6
feat: remove CI monkey patch
gomesalexandre Apr 9, 2024
2556c8e
feat: add .git-blame-ignore-revs
gomesalexandre Apr 9, 2024
02a9faf
feat: bring back monkey
gomesalexandre Apr 9, 2024
9ef1c87
feat: use zgosalvez/github-actions-report-lcov@v3 in CI
gomesalexandre Apr 9, 2024
44f2715
feat: monkey patch non-100% coverage
gomesalexandre Apr 9, 2024
181a7d3
fix: syntax
gomesalexandre Apr 9, 2024
470a1f6
feat: correct lcov.info loc
gomesalexandre Apr 9, 2024
abebf03
feat: use github-actions-report-lcov latest
gomesalexandre Apr 9, 2024
da55209
feat: upload and download lcov report
gomesalexandre Apr 9, 2024
91b2cde
feat: foudry as working dir
gomesalexandre Apr 9, 2024
8f7fbf6
feat: attempt 2
gomesalexandre Apr 9, 2024
1eaf228
feat: last attempt
gomesalexandre Apr 9, 2024
e5e112f
feat: rage quit
gomesalexandre Apr 9, 2024
1933c1b
fix: rebase issues
woodenfurniture Apr 10, 2024
3365d89
chore: lint
gomesalexandre Apr 10, 2024
4baa74e
feat: lint config
gomesalexandre Apr 10, 2024
beec29c
feat: actually lint
gomesalexandre Apr 10, 2024
630e5e9
feat: blame ignore rev
gomesalexandre Apr 10, 2024
476030f
fix: rebase issues
woodenfurniture Apr 10, 2024
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
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Initial linting
1696c504527d64d9b22cefe03e38ac1f41c90268
17 changes: 12 additions & 5 deletions .github/workflows/foundry.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: test
name: Foundry

on: workflow_dispatch
on:
workflow_dispatch:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

env:
FOUNDRY_PROFILE: ci
Expand All @@ -22,9 +27,7 @@ jobs:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
uses: foundry-rs/foundry-toolchain@v1.2.0

- name: Run Forge build
run: |
Expand All @@ -36,3 +39,7 @@ jobs:
run: |
forge test -vvv
id: test
- name: Generate coverage report
run: |
forge coverage --report summary
id: coverage
Comment on lines +42 to +45
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this doesn't exit 1 on non-100% coverage unfortunately. Since the output:

Compiling 39 files with 0.8.25
Solc 0.8.25 finished in 2.42s
Compiler run �[32msuccessful!�[0m
Analysing contracts...
Running tests...
| File                  | % Lines         | % Statements    | % Branches      | % Funcs         |
|-----------------------|-----------------|-----------------|-----------------|-----------------|
| src/FoxStaking.sol    | 100.00% (37/37) | 100.00% (38/38) | 100.00% (14/14) | 100.00% (14/14) |
| test/FoxStaking.t.sol | 100.00% (1/1)   | 100.00% (1/1)   | 100.00% (0/0)   | 100.00% (1/1)   |
| Total                 | 100.00% (38/38) | 100.00% (39/39) | 100.00% (14/14) | 100.00% (15/15) |

is more than likely to stay pretty much the same as we're not going to add more contract files/test files, do we want to have some smallish awk/sed/grep script here to exit 1 on non-100% coverage so that CI can fail? e.g something like this (ChatGPT-generated, untested but the idea is to rely on the output being consistent, filter out the irrelevant lines, and ensure both FoxStaking, FoxStaking.t and Total lines are 100.00%.

- name: Check coverage for 100%
  run: |
    forge coverage --report summary | tee coverage.txt
    # Assuming the coverage summary always starts at a known line after "Running tests..."
    tail -n +10 coverage.txt > trimmed_coverage.txt
    if grep -v '100.00%' trimmed_coverage.txt; then
      echo "Not all coverage metrics are 100%"
      exit 1
    else
      echo "All coverage metrics are 100%"
    fi

Alternatively, forge coverage can output lcov which we may be able to use instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: Using lcov to fail CI on non-100% :sad: :

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll likely have more files as our test suites expand, but simply checking the total should be totally sufficient.

Could easily have a brute force check of the test with a regex to assert that any number preceding a % symbol is the string 100.00, which would cover all files regardless of how many we add in the future

16 changes: 16 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"plugins": ["prettier-plugin-solidity"],
"overrides": [
{
"files": "*.sol",
"options": {
"parser": "solidity-parse",
"printWidth": 80,
"tabWidth": 4,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false
}
}
]
}
12 changes: 0 additions & 12 deletions foundry/script/Counter.s.sol

This file was deleted.

25 changes: 14 additions & 11 deletions foundry/src/FoxStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Pausable} from "@openzeppelin/contracts/utils/Pausable.sol";
import {IFoxStaking, StakingInfo} from "./IFoxStaking.sol";
import {console} from "forge-std/Script.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

contract FoxStaking is
IFoxStaking,
Ownable(msg.sender), // Deployer is the owner
Pausable
{
using SafeERC20 for IERC20;
IERC20 public foxToken;
mapping(address => StakingInfo) public stakingInfo;

Expand All @@ -32,6 +33,7 @@ contract FoxStaking is
event Withdraw(address indexed account, uint256 amount);
event SetRuneAddress(
address indexed account,
string indexed oldRuneAddress,
string indexed newRuneAddress
);

Expand Down Expand Up @@ -95,13 +97,12 @@ contract FoxStaking is
uint256 amount,
string memory runeAddress
) external whenNotPaused whenStakingNotPaused {
require(bytes(runeAddress).length > 0, "Rune address cannot be empty");
require(amount > 0, "FOX amount to stake must be greater than 0");
// Transfer fundus from msg.sender to contract assuming allowance has been set - here goes nothing
require(
foxToken.transferFrom(msg.sender, address(this), amount),
"Transfer failed"
bytes(runeAddress).length == 43,
"Rune address must be 43 characters"
);
require(amount > 0, "FOX amount to stake must be greater than 0");
foxToken.safeTransferFrom(msg.sender, address(this), amount);
woodenfurniture marked this conversation as resolved.
Show resolved Hide resolved

StakingInfo storage info = stakingInfo[msg.sender];
info.stakingBalance += amount;
Expand Down Expand Up @@ -138,17 +139,19 @@ contract FoxStaking is
require(block.timestamp >= info.cooldownExpiry, "Not cooled down yet");
uint256 withdrawAmount = info.unstakingBalance;
info.unstakingBalance = 0;
require(
foxToken.transfer(msg.sender, withdrawAmount),
"Transfer failed"
);
foxToken.safeTransfer(msg.sender, withdrawAmount);
woodenfurniture marked this conversation as resolved.
Show resolved Hide resolved
emit Withdraw(msg.sender, withdrawAmount);
}

function setRuneAddress(string memory runeAddress) external {
require(
bytes(runeAddress).length == 43,
"Rune address must be 43 characters"
);
StakingInfo storage info = stakingInfo[msg.sender];
string memory oldRuneAddress = info.runeAddress;
info.runeAddress = runeAddress;
emit SetRuneAddress(msg.sender, runeAddress);
emit SetRuneAddress(msg.sender, oldRuneAddress, runeAddress);
}

function balanceOf(address account) external view returns (uint256 total) {
Expand Down
13 changes: 5 additions & 8 deletions foundry/src/IFoxStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
pragma solidity ^0.8.25;

struct StakingInfo {
uint256 stakingBalance;
uint256 unstakingBalance;
uint256 cooldownExpiry;
string runeAddress;
uint256 stakingBalance;
uint256 unstakingBalance;
uint256 cooldownExpiry;
string runeAddress;
}


/// @notice This interface outlines the functions for staking FOX tokens, managing RUNE addresses for rewards, and claiming 'em.
interface IFoxStaking {
/// @notice Pauses deposits
Expand Down Expand Up @@ -59,7 +58,5 @@ interface IFoxStaking {
/// This can be initiated by any address with any address as param, as this has view modifier i.e everything is public on-chain
/// @param account The address we're getting the staked FOX balance for.
/// @return total The total amount of FOX tokens held.
function balanceOf(
address account
) external view returns (uint256 total);
function balanceOf(address account) external view returns (uint256 total);
}
Loading