Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
875 changes: 875 additions & 0 deletions contracts-abi/abi/FastSettlementV3.abi

Large diffs are not rendered by default.

457 changes: 457 additions & 0 deletions contracts-abi/abi/IFastSettlementV3.abi

Large diffs are not rendered by default.

1,984 changes: 1,984 additions & 0 deletions contracts-abi/clients/FastSettlementV3/FastSettlementV3.go

Large diffs are not rendered by default.

933 changes: 933 additions & 0 deletions contracts-abi/clients/IFastSettlementV3/IFastSettlementV3.go

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions contracts-abi/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module github.com/primev/fastprotocolapp/contracts-abi

go 1.22

require github.com/ethereum/go-ethereum v1.14.9

require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect
github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/holiman/uint256 v1.3.1 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
188 changes: 188 additions & 0 deletions contracts-abi/go.sum

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions contracts-abi/script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# Generate Go bindings for FastSettlement contracts
# Run from the contracts-abi directory

set -e

# Define paths
CONTRACTS_DIR="../contracts"
ABI_DIR="./abi"
GO_CODE_BASE_DIR="./clients"

# Create directories
mkdir -p "$ABI_DIR"
mkdir -p "$GO_CODE_BASE_DIR"

# Compile contracts with forge
echo "Compiling contracts..."
forge compile --root "$CONTRACTS_DIR"

# Function to extract and save the ABI
extract_and_save_abi() {
local json_file="$1"
local abi_file="$2"
echo "Extracting ABI: $json_file -> $abi_file"
jq .abi "$json_file" > "$abi_file"
}

# Function to generate Go code from ABI
generate_go_code() {
local abi_file="$1"
local contract_name="$2"
local pkg_name="$3"

local contract_dir="$GO_CODE_BASE_DIR/$contract_name"
mkdir -p "$contract_dir"

echo "Generating Go bindings: $contract_name"
abigen --abi "$abi_file" --pkg "$pkg_name" --out "$contract_dir/$contract_name.go"
}

# Extract ABIs
extract_and_save_abi "$CONTRACTS_DIR/out/FastSettlementV3.sol/FastSettlementV3.json" "$ABI_DIR/FastSettlementV3.abi"
extract_and_save_abi "$CONTRACTS_DIR/out/IFastSettlementV3.sol/IFastSettlementV3.json" "$ABI_DIR/IFastSettlementV3.abi"

echo "ABI files extracted successfully."

# Generate Go bindings
generate_go_code "$ABI_DIR/FastSettlementV3.abi" "FastSettlementV3" "fastsettlementv3"
generate_go_code "$ABI_DIR/IFastSettlementV3.abi" "IFastSettlementV3" "ifastsettlementv3"

echo "Go bindings generated successfully in $GO_CODE_BASE_DIR"
222 changes: 222 additions & 0 deletions contracts/script/DeployFastSettlementV3.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Deployment using trezor
//
// - DRY RUN:
// forge script script/DeployFastSettlementV3.s.sol:DeployFastSettlementV3 \
// --rpc-url $RPC_URL \
// --sender <TREZOR_ADDRESS> \
// -vvvv
//
// - EXECUTE DEPLOYMENT:
// forge script script/DeployFastSettlementV3.s.sol:DeployFastSettlementV3 \
// --rpc-url $RPC_URL \
// --broadcast \
// --verify \
// --etherscan-api-key $ETHERSCAN_API_KEY \
// --trezor \
// --sender <TREZOR_ADDRESS> \
// -vvvv

pragma solidity ^0.8.24;

import {Script} from "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {FastSettlementV3} from "../src/FastSettlementV3.sol";

/// @dev Deploy script for FastSettlementV3 contract
contract DeployFastSettlementV3 is Script {
struct DeploymentParams {
address owner;
address executor;
address treasury;
address permit2;
address weth;
address[] initialSwapTargets;
}

struct DeploymentAddresses {
address implementation;
address proxy;
address fastSettlement;
}

// =============================================================
// CONFIGURATION
// =============================================================

// Ethereum Mainnet addresses
address constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant PRIMEV_TEAM_MULTISIG = 0x9101eda106A443A0fA82375936D0D1680D5a64F5;
address constant TREASURY = 0xfA0B0f5d298d28EFE4d35641724141ef19C05684;
address constant EXECUTOR = 0x959DAD78D5B68986A43cd270134A2704A990AA68;

// =============================================================
// MAIN FUNCTION
// =============================================================

/// @dev Main deployment function
/// @dev Signer is determined by CLI flags: --trezor, --ledger, or --private-key
function run() external {
DeploymentParams memory params = _loadAndValidateParams();
_logDeploymentParams(params);

// vm.startBroadcast() uses the signer from CLI flags
vm.startBroadcast();

DeploymentAddresses memory addresses = _deploy(params);

vm.stopBroadcast();

_verifyDeployment(addresses, params);
_logDeploymentSummary(addresses);
}

/// @dev Loads and validates deployment parameters from constants
function _loadAndValidateParams() internal pure returns (DeploymentParams memory) {
// Barter swap router - whitelisted at deployment
address[] memory initialSwapTargets = new address[](1);
initialSwapTargets[0] = 0x179dC3fb0F2230094894317f307241A52CdB38Aa;

_validateParams(PRIMEV_TEAM_MULTISIG, EXECUTOR, TREASURY, PERMIT2, WETH);

return
DeploymentParams({
owner: PRIMEV_TEAM_MULTISIG,
executor: EXECUTOR,
treasury: TREASURY,
permit2: PERMIT2,
weth: WETH,
initialSwapTargets: initialSwapTargets
});
}

/// @dev Validates deployment parameters
function _validateParams(
address owner,
address executor,
address treasury,
address permit2,
address weth
) internal pure {
require(owner != address(0), "DeployScript: owner cannot be zero address");
require(
executor != address(0),
"DeployScript: executor cannot be zero address - UPDATE EXECUTOR CONSTANT"
);
require(treasury != address(0), "DeployScript: treasury cannot be zero address");
require(permit2 != address(0), "DeployScript: permit2 cannot be zero address");
require(weth != address(0), "DeployScript: weth cannot be zero address");
}

/// @dev Deploys implementation and proxy contracts
/// @dev In dry run mode (without --broadcast), Foundry simulates the deployment
/// @dev In broadcast mode (with --broadcast), this actually deploys to the network
function _deploy(DeploymentParams memory params) internal returns (DeploymentAddresses memory) {
address implementation = _deployImplementation(params);
address proxy = _deployProxy(implementation, params);
address fastSettlement = address(proxy);

return
DeploymentAddresses({
implementation: implementation,
proxy: proxy,
fastSettlement: fastSettlement
});
}

/// @dev Deploys the implementation contract (with immutables set in constructor)
function _deployImplementation(DeploymentParams memory params) internal returns (address) {
console.log("\n=== Deploying Implementation ===");
FastSettlementV3 implementation = new FastSettlementV3(params.permit2, params.weth);
console.log("Implementation deployed at:", address(implementation));
require(
address(implementation) != address(0),
"DeployScript: implementation deployment failed"
);
return address(implementation);
}

/// @dev Deploys the proxy contract with initialization
function _deployProxy(
address implementation,
DeploymentParams memory params
) internal returns (address) {
console.log("\n=== Deploying Proxy ===");
require(implementation != address(0), "DeployScript: implementation address is zero");

bytes memory initData = abi.encodeCall(
FastSettlementV3.initialize,
(params.owner, params.executor, params.treasury, params.initialSwapTargets)
);

require(initData.length > 0, "DeployScript: initData cannot be empty");

ERC1967Proxy proxy = new ERC1967Proxy(implementation, initData);
address proxyAddress = address(proxy);
console.log("Proxy deployed at:", proxyAddress);
require(proxyAddress != address(0), "DeployScript: proxy deployment failed");

return proxyAddress;
}

/// @dev Verifies the deployment was successful
function _verifyDeployment(
DeploymentAddresses memory addresses,
DeploymentParams memory params
) internal view {
console.log("\n=== Verifying Deployment ===");
FastSettlementV3 settlement = FastSettlementV3(payable(addresses.fastSettlement));

require(addresses.implementation != address(0), "DeployScript: implementation is zero");
require(addresses.proxy != address(0), "DeployScript: proxy is zero");
require(addresses.fastSettlement != address(0), "DeployScript: fastSettlement is zero");
require(
addresses.implementation != addresses.proxy,
"DeployScript: implementation and proxy cannot be same"
);

// Verify immutables
require(address(settlement.PERMIT2()) == params.permit2, "DeployScript: PERMIT2 mismatch");
require(address(settlement.WETH()) == params.weth, "DeployScript: WETH mismatch");

// Verify initialization
require(settlement.executor() == params.executor, "DeployScript: executor mismatch");
require(settlement.treasury() == params.treasury, "DeployScript: treasury mismatch");

console.log("PERMIT2:", address(settlement.PERMIT2()));
console.log("WETH:", address(settlement.WETH()));
console.log("Executor:", settlement.executor());
console.log("Treasury:", settlement.treasury());
console.log("Owner:", settlement.owner());
console.log("Pending Owner:", settlement.pendingOwner());
console.log("Deployment verified successfully");
}

// =============================================================
// LOGGING FUNCTIONS
// =============================================================

/// @dev Logs deployment parameters
function _logDeploymentParams(DeploymentParams memory params) internal pure {
console.log("\n=== Deployment Parameters ===");
console.log("Owner:", params.owner);
console.log("Executor:", params.executor);
console.log("Treasury:", params.treasury);
console.log("Permit2:", params.permit2);
console.log("WETH:", params.weth);
console.log("Initial Swap Targets:", params.initialSwapTargets.length);
}

/// @dev Logs deployment summary
function _logDeploymentSummary(DeploymentAddresses memory addresses) internal pure {
console.log("\n=== Deployment Summary ===");
console.log("Implementation:", addresses.implementation);
console.log("Proxy:", addresses.proxy);
console.log("FastSettlementV3 (proxy):", addresses.fastSettlement);
console.log("\n=== NEXT STEPS ===");
console.log("1. Configure swap targets via setSwapTargets()");
console.log("2. Verify contract on Etherscan (if not auto-verified)");
console.log("\nDeployment completed successfully!");
}
}
4 changes: 3 additions & 1 deletion contracts/src/FastSettlementV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,15 @@ contract FastSettlementV3 is
}

function initialize(
address _owner,
address _executor,
address _treasury,
address[] calldata _initialSwapTargets
) public initializer {
if (_owner == address(0)) revert BadOwner();
if (_treasury == address(0)) revert BadTreasury();
if (_executor == address(0)) revert BadExecutor();
__Ownable_init(msg.sender);
__Ownable_init(_owner);
executor = _executor;
treasury = _treasury;

Expand Down
1 change: 1 addition & 0 deletions contracts/src/interfaces/IFastSettlementV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ interface IFastSettlementV3 {

error IntentExpired();
error BadNonce();
error BadOwner();
error BadTreasury();
error BadExecutor();
error BadRecipient();
Expand Down
5 changes: 4 additions & 1 deletion contracts/test/FastSettlementV3.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ contract FastSettlementV3Test is Test {
FastSettlementV3 impl = new FastSettlementV3(address(permit2), address(weth));
ERC1967Proxy proxy = new ERC1967Proxy(
address(impl),
abi.encodeCall(FastSettlementV3.initialize, (executor, treasury, initialTargets))
abi.encodeCall(
FastSettlementV3.initialize,
(address(this), executor, treasury, initialTargets)
)
);
settlement = FastSettlementV3(payable(address(proxy)));

Expand Down
2 changes: 1 addition & 1 deletion contracts/test/FastSettlementV3_Integration.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ contract FastSettlementV3IntegrationTest is Test {
FastSettlementV3 impl = new FastSettlementV3(permit2, address(weth));
ERC1967Proxy proxy = new ERC1967Proxy(
address(impl),
abi.encodeCall(FastSettlementV3.initialize, (executor, treasury, initialTargets))
abi.encodeCall(FastSettlementV3.initialize, (owner, executor, treasury, initialTargets))
);
settlement = FastSettlementV3(payable(address(proxy)));
vm.stopPrank();
Expand Down
Loading