An open API service indexing awesome lists of open source software.

https://github.com/cowprotocol/hooks-trampoline

A dedicated trampoline contract for executing user-specified hooks.
https://github.com/cowprotocol/hooks-trampoline

Last synced: 8 months ago
JSON representation

A dedicated trampoline contract for executing user-specified hooks.

Awesome Lists containing this project

README

          

# Hooks Trampoline

Hooks are a CoW Protocol feature that allow traders to specify custom Ethereum
calls as part of their order to get executed atomically in the same transaction
as they trade.

The `HooksTrampoline` contract protects the protocol from two things:

- Executing calls from the privileged context of the settlement contract. Fees
are accrued in the contract, and users could simply specify hooks that
`ERC20.transfer(user, amount)` if the calling context for user hooks were the
settlement contract.
- Reverting unnecessary hooks during a settlement. This can cause a two issues:
- `Interaction`s from the settlement contract are called with all remaining
`gasleft()`. This means, that a revert from an `INVALID` opcode for example,
would consume 63/64ths of the total transaction gas. This means that hooks
can make settlements extremely expensive for nothing.
- Other orders being executed as part of the settlement would also not be
included.

As such, the `HooksTrampoline` contract is designed to execute user-specified
hooks:

1. From an unprivileged context (the `HooksTrampoline` contract instead of the
CoW Protocol settlement contract).
2. Specify a gas limit, to cap `INVALID` opcodes from consuming too much gas.
3. Allow the calls to revert.

In addition, the `HooksTrampoline` also only allows calls from the settlement
contract. This means that hook implementations can add checks that ensure that
they are only called from within a settlement:

```solidity
require(msg.sender == HOOKS_TRAMPOLINE_ADDRESS, "not a settlement");
```

## Settlement Diagram

```mermaid
sequenceDiagram
participant Solver
participant Settlement
participant HooksTrampoline
participant Hook

Solver->>Settlement: settle
activate Settlement

Settlement->>HooksTrampoline: execute
activate HooksTrampoline
loop pre-hooks
HooksTrampoline->>Hook: call
activate Hook

Hook->>HooksTrampoline: return/revert
deactivate Hook
end
HooksTrampoline->>Settlement: return
deactivate HooksTrampoline

Settlement->>Settlement: swap

Settlement->>HooksTrampoline: execute
activate HooksTrampoline
loop post-hooks
HooksTrampoline->>Hook: call
activate Hook

Hook->>HooksTrampoline: return/revert
deactivate Hook
end
HooksTrampoline->>Settlement: return
deactivate HooksTrampoline

Settlement->>Solver: return
deactivate Settlement
```

## Development

### Installation

This project uses [Foundry](https://book.getfoundry.sh/).

Additional dependencies can be installed with:

```sh
forge install
```

### Test

```sh
forge test
```

### Deployment

Copy `.env.sample` to `.env` and fill each variable with the necessary
information.

You can do a test run of the transaction with the following command:

```sh
source .env
forge script script/DeployHooksTrampoline.s.sol -vvvv --rpc-url "$ETH_RPC_URL"
```

The following command executes the deployment transaction onchain and verifies
the contract code on the block explorer.

```sh
source .env
forge script script/DeployHooksTrampoline.s.sol -vvvv --rpc-url "$ETH_RPC_URL" --verify --verifier-url "$VERIFIER_URL" --broadcast
```

#### Deployment addresses

The file [`networks.json`](./networks.json) lists all official deployments of the contracts in this repository by chain id.

Update the file with:

```sh
bash dev/generate-networks-file.sh > networks.json
```

## Verification

If you deployed the contract passing `--verify`, the contract will be verified so you can skip this step. However, if you didn't, or the verification failed, you can verify the contract manually with the following command:

```sh
source .env

forge verify-contract 0x60Bf78233f48eC42eE3F101b9a05eC7878728006 src/HooksTrampoline.sol:HooksTrampoline --guess-constructor-args --etherscan-api-key $ETHERSCAN_API_KEY --verifier-url $VERIFIER_URL --verifier $VERIFIER --watch
```