-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Init forge and add few tests to LockContract
* Init forge and some tests Co-authored-by: Kamil Koczurek <[email protected]>
- Loading branch information
Showing
31 changed files
with
22,788 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
name: Foundry test suite | ||
on: [push] | ||
|
||
jobs: | ||
solidity-tests: | ||
name: Run solidity tests in foundry | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Install Foundry | ||
uses: foundry-rs/foundry-toolchain@v1 | ||
|
||
- name: Run tests | ||
run: cd gnt2-contracts && forge test -vvv | ||
|
||
- name: Run snapshot | ||
run: cd gnt2-contracts && forge snapshot | ||
|
||
- name: Upload snapshot | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: gas-snapshot.txt | ||
path: gnt2-contracts/.gas-snapshot | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ build/ | |
dist/ | ||
/rinkeby-deployment.json | ||
cache/ | ||
/out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
## Foundry | ||
|
||
**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** | ||
|
||
Foundry consists of: | ||
|
||
- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). | ||
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. | ||
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. | ||
- **Chisel**: Fast, utilitarian, and verbose solidity REPL. | ||
|
||
## Documentation | ||
|
||
https://book.getfoundry.sh/ | ||
|
||
## Usage | ||
|
||
### Build | ||
|
||
```shell | ||
$ forge build | ||
``` | ||
|
||
### Test | ||
|
||
```shell | ||
$ forge test | ||
``` | ||
|
||
### Format | ||
|
||
```shell | ||
$ forge fmt | ||
``` | ||
|
||
### Gas Snapshots | ||
|
||
```shell | ||
$ forge snapshot | ||
``` | ||
|
||
### Anvil | ||
|
||
```shell | ||
$ anvil | ||
``` | ||
|
||
### Deploy | ||
|
||
```shell | ||
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key> | ||
``` | ||
|
||
### Cast | ||
|
||
```shell | ||
$ cast <subcommand> | ||
``` | ||
|
||
### Help | ||
|
||
```shell | ||
$ forge --help | ||
$ anvil --help | ||
$ cast --help | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[profile.default] | ||
# do not include all contracts | ||
src = "src/dummy" | ||
# Inlucde only contracts in the following paths | ||
include_paths = ["test", "src/contracts/GNT2", "src/contracts/LockPayment", "src/contracts/MultiTransfer", "src/contracts/WrapperCall"] | ||
out = "out" | ||
remappings = ["@openzeppelin/=node_modules/@openzeppelin/"] | ||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options | ||
ignored_warnings_from = ["src/contracts/currentlyDeployed/GNT/Token.sol", "src/contracts/currentlyDeployed/MultiSigWallet/MultiSigWallet.sol"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
pragma solidity ^0.8.13; | ||
|
||
import "forge-std/console.sol"; | ||
import "forge-std/Test.sol"; | ||
import "forge-std/mocks/MockERC20.sol"; | ||
import {ILockPayment, LockPayment, IERC20 as L_IERC20} from "../src/contracts/LockPayment/LockPayment.sol"; | ||
|
||
contract MockToken is MockERC20 { | ||
constructor(string memory name, string memory symbol, uint8 decimals) { | ||
initialize(name, symbol, decimals); | ||
} | ||
|
||
function mint(address to, uint256 value) public virtual { | ||
_mint(to, value); | ||
} | ||
|
||
function burn(address from, uint256 value) public virtual { | ||
_burn(from, value); | ||
} | ||
} | ||
|
||
contract LockPaymentTest is Test { | ||
MockToken internal token; | ||
LockPayment internal testee; | ||
|
||
function setUp() public { | ||
token = new MockToken("Test Golem Network Token", "tGLM", 18); | ||
testee = new LockPayment(L_IERC20(address(token))); | ||
} | ||
|
||
function test_DepositCreate() public { | ||
helper_funds(msg.sender, 3, true); | ||
|
||
uint256 expectedId = uint256(uint160(msg.sender)) << 96; | ||
address expectedSpender = address(2); | ||
vm.expectEmit(); | ||
emit LockPayment.DepositCreated(expectedId, expectedSpender); | ||
|
||
vm.prank(msg.sender); | ||
uint256 depositId = testee.createDeposit(0, address(2), 2, 1, 0); | ||
|
||
assertEq(depositId, expectedId); | ||
assertEq(token.balanceOf(msg.sender), 0); | ||
assertEq(token.balanceOf(address(testee)), 3); | ||
|
||
ILockPayment.DepositView memory deposit = testee.getDeposit(depositId); | ||
assertEq(deposit.id, depositId); | ||
assertEq(deposit.funder, msg.sender); | ||
assertEq(deposit.spender, expectedSpender); | ||
assertEq(deposit.amount, 2); | ||
assertEq(deposit.validTo, 0); | ||
} | ||
|
||
function test_DepositCreate_NonceReused() public { | ||
helper_funds(msg.sender, 6, true); | ||
|
||
vm.prank(msg.sender); | ||
testee.createDeposit(12, address(2), 2, 1, 0); | ||
|
||
assertEq(token.balanceOf(msg.sender), 3); | ||
assertEq(token.balanceOf(address(testee)), 3); | ||
|
||
vm.prank(msg.sender); | ||
vm.expectRevert("deposits[id].spender == address(0)"); | ||
testee.createDeposit(12, address(2), 2, 1, 0); | ||
|
||
assertEq(token.balanceOf(msg.sender), 3); | ||
assertEq(token.balanceOf(address(testee)), 3); | ||
} | ||
|
||
function test_DepositCreate_ZeroAmount() public { | ||
helper_funds(msg.sender, 3, true); | ||
|
||
vm.prank(msg.sender); | ||
vm.expectRevert("amount > 0"); | ||
testee.createDeposit(0, address(2), 0, 1, 0); | ||
|
||
assertEq(token.balanceOf(msg.sender), 3); | ||
assertEq(token.balanceOf(address(testee)), 0); | ||
} | ||
|
||
function test_DepositCreate_NullSpender() public { | ||
helper_funds(msg.sender, 3, true); | ||
|
||
vm.prank(msg.sender); | ||
vm.expectRevert("spender cannot be null address"); | ||
testee.createDeposit(0, address(0), 2, 1, 0); | ||
|
||
assertEq(token.balanceOf(msg.sender), 3); | ||
assertEq(token.balanceOf(address(testee)), 0); | ||
} | ||
|
||
function test_DepositCreate_SelfSpender() public { | ||
helper_funds(msg.sender, 3, true); | ||
|
||
vm.prank(msg.sender); | ||
vm.expectRevert("spender cannot be funder"); | ||
testee.createDeposit(0, msg.sender, 2, 1, 0); | ||
|
||
assertEq(token.balanceOf(msg.sender), 3); | ||
assertEq(token.balanceOf(address(testee)), 0); | ||
} | ||
|
||
function test_CloseDeposit() public { | ||
address spender = address(21); | ||
|
||
helper_funds(msg.sender, 3, true); | ||
|
||
vm.prank(msg.sender); | ||
uint256 depositId = testee.createDeposit(12, spender, 2, 1, 0); | ||
assertEq(token.balanceOf(msg.sender), 0); | ||
assertEq(token.balanceOf(spender), 0); | ||
assertEq(token.balanceOf(address(testee)), 3); | ||
|
||
vm.expectEmit(); | ||
emit LockPayment.DepositFeeTransfer(depositId, spender, 1); | ||
vm.expectEmit(); | ||
emit LockPayment.DepositClosed(depositId, spender); | ||
|
||
vm.prank(spender); | ||
testee.closeDeposit(depositId); | ||
|
||
assertEq(token.balanceOf(msg.sender), 2); | ||
assertEq(token.balanceOf(spender), 1); | ||
assertEq(token.balanceOf(address(testee)), 0); | ||
|
||
ILockPayment.DepositView memory deposit = testee.getDeposit(depositId); | ||
assertEq(deposit.id, depositId); | ||
assertEq(deposit.funder, msg.sender); | ||
assertEq(deposit.spender, address(0xBad)); | ||
assertEq(deposit.amount, 0); | ||
assertEq(deposit.validTo, 0); | ||
} | ||
|
||
function helper_funds(address addr, uint256 amount, bool approve_testee) internal { | ||
token.mint(addr, amount); | ||
assertEq(token.balanceOf(addr), amount); | ||
|
||
if(approve_testee) { | ||
vm.prank(msg.sender); | ||
token.approve(address(testee), amount); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.6.2 <0.9.0; | ||
|
||
import {StdStorage} from "./StdStorage.sol"; | ||
import {Vm, VmSafe} from "./Vm.sol"; | ||
|
||
abstract contract CommonBase { | ||
// Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. | ||
address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); | ||
// console.sol and console2.sol work by executing a staticcall to this address. | ||
address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; | ||
// Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. | ||
address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; | ||
// Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. | ||
address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); | ||
// Address of the test contract, deployed by the DEFAULT_SENDER. | ||
address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; | ||
// Deterministic deployment address of the Multicall3 contract. | ||
address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; | ||
// The order of the secp256k1 curve. | ||
uint256 internal constant SECP256K1_ORDER = | ||
115792089237316195423570985008687907852837564279074904382605163141518161494337; | ||
|
||
uint256 internal constant UINT256_MAX = | ||
115792089237316195423570985008687907853269984665640564039457584007913129639935; | ||
|
||
Vm internal constant vm = Vm(VM_ADDRESS); | ||
StdStorage internal stdstore; | ||
} | ||
|
||
abstract contract TestBase is CommonBase {} | ||
|
||
abstract contract ScriptBase is CommonBase { | ||
VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.6.2 <0.9.0; | ||
|
||
// 💬 ABOUT | ||
// Forge Std's default Script. | ||
|
||
// 🧩 MODULES | ||
import {console} from "./console.sol"; | ||
import {console2} from "./console2.sol"; | ||
import {safeconsole} from "./safeconsole.sol"; | ||
import {StdChains} from "./StdChains.sol"; | ||
import {StdCheatsSafe} from "./StdCheats.sol"; | ||
import {stdJson} from "./StdJson.sol"; | ||
import {stdMath} from "./StdMath.sol"; | ||
import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; | ||
import {StdStyle} from "./StdStyle.sol"; | ||
import {StdUtils} from "./StdUtils.sol"; | ||
import {VmSafe} from "./Vm.sol"; | ||
|
||
// 📦 BOILERPLATE | ||
import {ScriptBase} from "./Base.sol"; | ||
|
||
// ⭐️ SCRIPT | ||
abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { | ||
// Note: IS_SCRIPT() must return true. | ||
bool public IS_SCRIPT = true; | ||
} |
Oops, something went wrong.