diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index da0bdcfa..63a67649 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -73,6 +73,15 @@ jobs: - name: Run rustfmt run: cargo +${{ steps.nightly.outputs.version }} fmt -- --check + - name: Install foundry + uses: foundry-rs/foundry-toolchain@8f1998e9878d786675189ef566a2e4bf24869773 + with: + version: nightly-41d4e5437107f6f42c7711123890147bc736a609 + cache: false + + - name: Run forge fmt + run: FOUNDRY_FMT_SORT_INPUTS=false FOUNDRY_FMT_LINE_LENGTH=100 FOUNDRY_FMT_TABLE_WIDTH=2 FOUNDRY_FMT_BRACKET_SPACING=true FOUNDRY_FMT_INT_TYPES=preserve forge fmt --check $(find . -iname "*.sol") + machete: runs-on: ubuntu-latest steps: diff --git a/networks/ethereum/schnorr/contracts/Schnorr.sol b/networks/ethereum/schnorr/contracts/Schnorr.sol index 182e90e3..69dc208a 100644 --- a/networks/ethereum/schnorr/contracts/Schnorr.sol +++ b/networks/ethereum/schnorr/contracts/Schnorr.sol @@ -4,24 +4,22 @@ pragma solidity ^0.8.26; // See https://github.com/noot/schnorr-verify for implementation details library Schnorr { // secp256k1 group order - uint256 constant private Q = - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + uint256 private constant Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; // We fix the key to have: // 1) An even y-coordinate // 2) An x-coordinate < Q - uint8 constant private KEY_PARITY = 27; + uint8 private constant KEY_PARITY = 27; // px := public key x-coordinate, where the public key has an even y-coordinate // message := the message signed // c := Schnorr signature challenge // s := Schnorr signature solution - function verify( - bytes32 px, - bytes memory message, - bytes32 c, - bytes32 s - ) internal pure returns (bool) { + function verify(bytes32 px, bytes memory message, bytes32 c, bytes32 s) + internal + pure + returns (bool) + { // ecrecover = (m, v, r, s) -> key // We instead pass the following to obtain the nonce (not the key) // Then we hash it and verify it matches the challenge diff --git a/networks/ethereum/schnorr/contracts/tests/Schnorr.sol b/networks/ethereum/schnorr/contracts/tests/Schnorr.sol index 26be683d..11a3c3bc 100644 --- a/networks/ethereum/schnorr/contracts/tests/Schnorr.sol +++ b/networks/ethereum/schnorr/contracts/tests/Schnorr.sol @@ -4,12 +4,11 @@ pragma solidity ^0.8.26; import "../Schnorr.sol"; contract TestSchnorr { - function verify( - bytes32 public_key, - bytes calldata message, - bytes32 c, - bytes32 s - ) external pure returns (bool) { + function verify(bytes32 public_key, bytes calldata message, bytes32 c, bytes32 s) + external + pure + returns (bool) + { return Schnorr.verify(public_key, message, c, s); } } diff --git a/processor/ethereum/contracts/contracts/Router.sol b/processor/ethereum/contracts/contracts/Router.sol index 1d084698..136c1e62 100644 --- a/processor/ethereum/contracts/contracts/Router.sol +++ b/processor/ethereum/contracts/contracts/Router.sol @@ -35,7 +35,9 @@ contract Router { } event SeraiKeyUpdated(uint256 indexed nonce, bytes32 indexed key); - event InInstruction(address indexed from, address indexed coin, uint256 amount, bytes instruction); + event InInstruction( + address indexed from, address indexed coin, uint256 amount, bytes instruction + ); event Executed(uint256 indexed nonce, bytes32 indexed batch); error InvalidSignature(); @@ -62,10 +64,10 @@ contract Router { // updateSeraiKey validates the given Schnorr signature against the current public key, and if // successful, updates the contract's public key to the one specified. - function updateSeraiKey( - bytes32 newSeraiKey, - Signature calldata signature - ) external _updateSeraiKeyAtEndOfFn(_nonce, newSeraiKey) { + function updateSeraiKey(bytes32 newSeraiKey, Signature calldata signature) + external + _updateSeraiKeyAtEndOfFn(_nonce, newSeraiKey) + { bytes memory message = abi.encodePacked("updateSeraiKey", block.chainid, _nonce, newSeraiKey); _nonce++; @@ -74,25 +76,15 @@ contract Router { } } - function inInstruction( - address coin, - uint256 amount, - bytes memory instruction - ) external payable { + function inInstruction(address coin, uint256 amount, bytes memory instruction) external payable { if (coin == address(0)) { if (amount != msg.value) { revert InvalidAmount(); } } else { - (bool success, bytes memory res) = - address(coin).call( - abi.encodeWithSelector( - IERC20.transferFrom.selector, - msg.sender, - address(this), - amount - ) - ); + (bool success, bytes memory res) = address(coin).call( + abi.encodeWithSelector(IERC20.transferFrom.selector, msg.sender, address(this), amount) + ); // Require there was nothing returned, which is done by some non-standard tokens, or that the // ERC20 contract did in fact return true @@ -193,9 +185,9 @@ contract Router { // Perform the calls with a set gas budget (uint32 gas, bytes memory code) = abi.decode(transactions[i].destination, (uint32, bytes)); - address(this).call{ - gas: gas - }(abi.encodeWithSelector(Router.arbitaryCallOut.selector, code)); + address(this).call{ gas: gas }( + abi.encodeWithSelector(Router.arbitaryCallOut.selector, code) + ); } } } diff --git a/processor/ethereum/contracts/contracts/tests/ERC20.sol b/processor/ethereum/contracts/contracts/tests/ERC20.sol index f38bfea4..9ce4bad7 100644 --- a/processor/ethereum/contracts/contracts/tests/ERC20.sol +++ b/processor/ethereum/contracts/contracts/tests/ERC20.sol @@ -8,9 +8,11 @@ contract TestERC20 { function name() public pure returns (string memory) { return "Test ERC20"; } + function symbol() public pure returns (string memory) { return "TEST"; } + function decimals() public pure returns (uint8) { return 18; } @@ -29,11 +31,13 @@ contract TestERC20 { function balanceOf(address owner) public view returns (uint256) { return balances[owner]; } + function transfer(address to, uint256 value) public returns (bool) { balances[msg.sender] -= value; balances[to] += value; return true; } + function transferFrom(address from, address to, uint256 value) public returns (bool) { allowances[from][msg.sender] -= value; balances[from] -= value; @@ -45,6 +49,7 @@ contract TestERC20 { allowances[msg.sender][spender] = value; return true; } + function allowance(address owner, address spender) public view returns (uint256) { return allowances[owner][spender]; } diff --git a/processor/ethereum/deployer/contracts/Deployer.sol b/processor/ethereum/deployer/contracts/Deployer.sol index 24ea1cb4..ad217fdc 100644 --- a/processor/ethereum/deployer/contracts/Deployer.sol +++ b/processor/ethereum/deployer/contracts/Deployer.sol @@ -38,6 +38,7 @@ contract Deployer { uint64 block_number; address created_contract; } + mapping(bytes32 => Deployment) public deployments; error Reentrancy(); @@ -51,11 +52,15 @@ contract Deployer { bool called; // This contract doesn't have any other use of transient storage, nor is to be inherited, making // this usage of the zero address safe - assembly { called := tload(0) } + assembly { + called := tload(0) + } if (called) { revert Reentrancy(); } - assembly { tstore(0, 1) } + assembly { + tstore(0, 1) + } // Check this wasn't prior deployed bytes32 init_code_hash = keccak256(init_code);