Skip to content

Commit

Permalink
move faucet to holesky
Browse files Browse the repository at this point in the history
  • Loading branch information
Primata committed Oct 16, 2024
1 parent 370f9c2 commit 4cfa884
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@
[submodule "dispute-murky"]
path = protocol-units/dispute/lib/murky
url = https://github.com/dmfxyz/murky
[submodule "protocol-units/tokens/mock/testnet/holesky/lib/openzeppelin-contracts"]
path = protocol-units/tokens/mock/testnet/holesky/lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

- name: Show Forge version
run: |
forge --version
- name: Run Forge fmt
run: |
forge fmt --check
id: fmt

- name: Run Forge build
run: |
forge build --sizes
id: build

- name: Run Forge tests
run: |
forge test -vvv
id: test
14 changes: 14 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/

# Docs
docs/

# Dotenv file
.env
66 changes: 66 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/README.md
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
```
6 changes: 6 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
Submodule openzeppelin-contracts added at dbb610
5 changes: 5 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/
46 changes: 46 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/src/MOVEFaucet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function decimals() external view returns (uint8);
}

contract MOVEFaucet {

IERC20 public move;
uint256 public rateLimit = 1 days;
uint256 public amount = 10;
uint256 public maxBalance = 1;
address public owner;
mapping(address => uint256) public lastFaucetClaim;

constructor(IERC20 _move) {
move = _move;
owner = msg.sender;
}

function faucet() external payable {
require(msg.value == 10 ** 17, "MOVEFaucet: eth invalid amount");
require(move.balanceOf(msg.sender) < maxBalance * 10 ** move.decimals(), "MOVEFaucet: balance must be less than determined amount of MOVE");
require(block.timestamp - lastFaucetClaim[msg.sender] >= rateLimit, "MOVEFaucet: rate limit exceeded");
lastFaucetClaim[msg.sender] = block.timestamp;
require(move.transfer(msg.sender, amount * 10 ** move.decimals()), "MOVEFaucet: transfer failed");
}

function setConfig(uint256 _rateLimit, uint256 _amount, uint256 _maxBalance, address _owner) external {
require(msg.sender == owner, "MOVEFaucet: only owner can set config");
rateLimit = _rateLimit;
amount = _amount;
maxBalance = _maxBalance;
owner = _owner;

}

function withdraw() external {
require(msg.sender == owner, "MOVEFaucet: only owner can retrieve funds");
(bool status,) = owner.call{value: address(this).balance}("");
require(status == true, "error during transaction");
}
}
81 changes: 81 additions & 0 deletions protocol-units/tokens/mock/testnet/holesky/test/Faucet.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "forge-std/Test.sol";
import {MOVEFaucet, IERC20} from '../src/MOVEFaucet.sol';
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

contract MOVETokenDev is ERC20, AccessControl {

bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant MINTER_ADMIN_ROLE = keccak256("MINTER_ADMIN_ROLE");

/**
* @dev Initialize the contract
*/
constructor(address manager) ERC20("Movement", "MOVE") {
_mint(manager, 10000000000 * 10 ** decimals());
_grantRole(MINTER_ADMIN_ROLE, manager);
_grantRole(MINTER_ROLE, manager);
}

function grantRoles(address account) public onlyRole(DEFAULT_ADMIN_ROLE) {
_grantRole(MINTER_ADMIN_ROLE, account);
_grantRole(MINTER_ROLE, account);

}

function decimals() public pure override returns (uint8) {
return 8;
}
}

contract MOVEFaucetTest is Test {
MOVEFaucet public faucet;
MOVETokenDev public token;

fallback() external payable {}

function setUp() public {
token = new MOVETokenDev(address(this));
faucet = new MOVEFaucet(IERC20(address(token)));
}

function testFaucet() public {
vm.warp(1 days);

token.balanceOf(address(this));

token.transfer(address(faucet), 20 * 10 ** token.decimals());

vm.deal(address(0x1337), 2* 10**17);

vm.startPrank(address(0x1337));
vm.expectRevert("MOVEFaucet: eth invalid amount");
faucet.faucet{value: 10**16}();

faucet.faucet{value: 10**17}();
assertEq(token.balanceOf(address(0x1337)), 10 * 10 ** token.decimals());

vm.expectRevert("MOVEFaucet: balance must be less than determined amount of MOVE");
faucet.faucet{value: 10**17}();

token.transfer(address(0xdead), token.balanceOf(address(0x1337)));

vm.expectRevert("MOVEFaucet: rate limit exceeded");
faucet.faucet{value: 10**17}();

vm.warp(block.timestamp + 1 days);
faucet.faucet{value: 10**17}();
vm.stopPrank();
vm.prank(address(this));
uint256 balance = address(this).balance;
faucet.withdraw();
assertEq(address(faucet).balance, 0);
assertEq(address(this).balance, balance + 2*10**17);
}


}

0 comments on commit 4cfa884

Please sign in to comment.