# Smart Contracts

<table><thead><tr><th width="217.545792981082">Contract</th><th width="239.33333333333331">Address</th><th>Networks</th></tr></thead><tbody><tr><td>Account.sol</td><td>0x00000000AfCbce78c080F96032a5C1cB1b832D7B</td><td><a href="https://etherscan.io/address/0x00000000AfCbce78c080F96032a5C1cB1b832D7B#code"><code>mainnet</code></a>, <a href="https://rinkeby.etherscan.io/address/0x00000000AfCbce78c080F96032a5C1cB1b832D7B#code"><code>rinkeby</code></a></td></tr><tr><td>AccountFactory.sol</td><td>0xe925f84cA9Dd5b3844fC424861D7bDf9485761B6</td><td><a href="https://etherscan.io/address/0xe925f84cA9Dd5b3844fC424861D7bDf9485761B6#code"><code>mainnet</code></a>, <a href="https://goerli.etherscan.io/address/0xe925f84cA9Dd5b3844fC424861D7bDf9485761B6#code"><code>rinkeby</code></a></td></tr><tr><td>DeployAndCall.sol</td><td>0x452C31d60883F0CB51744Ab9fd01685d7443CA6f</td><td><a href="https://etherscan.io/address/0x452C31d60883F0CB51744Ab9fd01685d7443CA6f#code"><code>mainnet</code></a>, <a href="https://rinkeby.etherscan.io/address/0x452C31d60883F0CB51744Ab9fd01685d7443CA6f#code"><code>rinkeby</code></a></td></tr><tr><td>SaltedDeployer.sol</td><td>0x6b24634B517a63Ed0fa2a39977286e13e7E35E25</td><td><a href="https://etherscan.io/address/0x6b24634B517a63Ed0fa2a39977286e13e7E35E25#code"><code>mainnet</code></a>, <a href="https://rinkeby.etherscan.io/address/0x6b24634B517a63Ed0fa2a39977286e13e7E35E25#code"><code>rinkeby</code></a></td></tr><tr><td>LimitSwapVerifier.sol</td><td>0x53D468E719694f3e542Dda96a237Af08eb394f2C</td><td><a href="https://etherscan.io/address/0x53D468E719694f3e542Dda96a237Af08eb394f2C#code"><code>mainnet</code></a>, <a href="https://rinkeby.etherscan.io/address/0x53D468E719694f3e542Dda96a237Af08eb394f2C#code"><code>rinkeby</code></a></td></tr><tr><td>CancelVerifier.sol</td><td>0xE0670a90E67eda0126D54843267b27Ca6343B2d8</td><td><a href="https://etherscan.io/address/0xE0670a90E67eda0126D54843267b27Ca6343B2d8#code"><code>mainnet</code></a>, <a href="https://rinkeby.etherscan.io/address/0xE0670a90E67eda0126D54843267b27Ca6343B2d8#code"><code>rinkeby</code></a></td></tr></tbody></table>

## brink-core

The [brink-core](https://github.com/brinktrade/brink-core) repo contains core contracts for Brink accounts.

### Account

The [Account.sol](https://github.com/brinktrade/brink-core/blob/master/contracts/Account/Account.sol) contract is meant to be a canonical instance, deployed once, and used by many instances of [Proxy.sol](https://github.com/brinktrade/brink-core/blob/master/contracts/Proxy/Proxy.sol) via `delegatecall` proxied function calls. It contains all logic for proxy account interactions.

The Account contract exposes 4 functions that allow state changes to proxy account instances:

#### externalCall()

Makes a function call from the account proxy to an external contract using the `call` opcode. Can only be called directly by the proxy account owner. This function can be used to execute account actions that require calls to external contracts, such as an ERC20 transfer.

#### delegateCall()

Makes a delegated function call from the account proxy to an external contract using the `delegatecall` opcode. Can only be called directly by the proxy account owner. This function can be used to execute any call directly on the proxy account instance. It can be used to modify any state on the account. Practical examples of use include `sstore` execution, outgoing ETH transfers, or direct execution of complex logic such as a swap on an AMM.

#### metaDelegateCall()

Allows execution of a `delegatecall` permitted by an [EIP-712](https://eips.ethereum.org/EIPS/eip-712) message signed by the proxy account owner. Can be called by any address as long as a valid signed message is provided.

The `to` address of a `metaDelegateCall()` should be the address of a secure verifier contract (see [brink-verifiers](https://github.com/brinktrade/brink-verifiers) for examples). The `data` parameter contains the function call data to execute on the verifier contract. Both `to` and `data` must be included in the signed message.

#### metaPartialSignedDelegateCall()

Allows execution of a `delegatecall` permitted by an [EIP-712](https://eips.ethereum.org/EIPS/eip-712) message signed by the proxy account owner, with additional unsigned call data provided by the transaction executor. Can be called by any address as long as a valid signed message is provided.

The `to` address and `data` parameter behave the same way as they do in `metaDelegateCall()`. The `unsignedData` parameter is provided by the transaction executor, and is not included as part of the signed message. It is appended to `data` and executed on the verifier contract at the `to` address. The verifier must be set up to securely handle arbitrary execution of the unsigned portion of the call data it receives.

See the [LimitSwapVerifier.tokenToToken()](https://github.com/brinktrade/brink-verifiers/blob/master/contracts/Verifiers/LimitSwapVerifier.sol#L27) as an example of a verifier function that is designed to securely handle a partially signed delegate call. This function requires that the signed output, input, and expiry conditions are met, while allowing the executor to provide its own call data to source the limit swap.

### Proxy

The [Proxy.sol](https://github.com/brinktrade/brink-core/blob/master/contracts/Proxy/Proxy.sol) contract is a gas-optimized proxy instance deployed for each Brink account owner. This contract contains no specific logic for accounts. It uses `delegatecall` in a `fallback()` function to execute logic from the `implementation` address, which should be the canonical [Account.sol](https://github.com/brinktrade/brink-core/blob/master/contracts/Account/Account.sol) address.

Brink proxies can be upgraded by owner by modifying the `implementation` address at the storage location set by the `IMPLEMENTATION_PTR` constant. **We recommend that you do not modify the implementation address! Your account will no longer be supported by any of the Brink open source tools such as** [**brink-sdk**](https://github.com/brinktrade/brink-sdk)**.**

See <https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies> for general info on the proxy upgrade pattern.

### DeployAndCall

The [`DeployAndCall.sol`](https://github.com/brinktrade/brink-core/blob/master/contracts/Batched/DeployAndCall.sol) contract allows for contract deployment and execution of call data on the newly deployed contract in the same transaction. It is not Brink specific, but can be used by executors to conveniently execute meta transactions on undeployed Brink proxy accounts by batching deployment and call into a single transaction.

### CallExecutor

The [CallExecutor.sol](https://github.com/brinktrade/brink-core/blob/master/contracts/Called/CallExecutor.sol) contract can be used by verifier functions to securely execute arbitrary call data without exposing the proxy account as `msg.sender`.

See an example of use in [LimitSwapVerifier.tokenToToken()](https://github.com/brinktrade/brink-verifiers/blob/master/contracts/Verifiers/LimitSwapVerifier.sol#L39). If the arbitrary call data execution here was not proxied through CallExecutor, this verifier would unsafely allow execution of any external contract call directly from the account proxy instance. A malicious executor could use this to initiate a 3rd ERC20 transfer to their own address, after satisfying the verified swap conditions.

[*Goerli Address*](https://goerli.etherscan.io/address/0x79ee9ab99beb577ee852089588513192d63cbd14)*:* `0x79ee9ab99beb577ee852089588513192d63cbd14`

## brink-verifiers

The brink-verifiers repo contains contracts for Brink account signed messages. Verifiers are used to verify valid conditions for order execution, and to execute state changes that fulfill the conditions of an order.

### LimitSwapVerifier

The [LimitSwapVerifier.sol](https://github.com/brinktrade/brink-verifiers/blob/master/contracts/Verifiers/LimitSwapVerifier.sol) contract contains verifier functions for Brink limit swap orders. These are designed to be executed with `metaPartialDelegateCall()` signed messages. The input, output, and expiry parameters are signed by account owners. Additional unsigned data is provided by the transaction executor to source the swap output.

Limit swap verifier functions are un-opinionated about how swaps are sourced. They will succeed as long as the required swap output is provided, and allow no more than the specified swap input to be transferred out of the account.

*Note that the execution profit incentive for limit swaps is arbitrage based. The transaction executor can take a portion of input or output, as long as the verifier's requirements are met. There is a competitive incentive to source the swap efficiently, because a signed swap can only be executed once.*

#### tokenToToken()

Supports ERC20 to ERC20 signed swaps.

#### ethToToken()

Supports ETH to ERC20 signed swaps.

#### tokenToEth()

Supports ERC20 to ETH signed swaps.

### CancelVerifier

The [CancelVerifier.sol](https://github.com/brinktrade/brink-verifiers/blob/master/contracts/Verifiers/CancelVerifier.sol) contract contains a verifier function that invalidates an existing signed message, effectively cancelling the order associated with it. It writes to a `bit` and `bitmapIndex` which will invalidated any message that requires this `bit` and `bitmapIndex` to be empty. This can be used to cancel LimitSwapVerifier signed swaps, or any signed message type for a verifier that shares the same replay protection storage location.

*Note that there is no profit incentive for executors to cancel on an owner's behalf. CancelVerifier.cancel() is designed to be called directly by account owners using* [*Account.delegateCall()*](https://github.com/brinktrade/brink-core/blob/master/contracts/Account/Account.sol#L56)*.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://brink.gitbook.io/brink/developer-guides/smart-contracts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
