# Introduction

Anvil is a system of Ethereum-based smart contracts that manages collateral and issues fully secured credit. A primary example is a letter of credit (LOC), analogous to a paper bank cheque drawing verified funds, providing an economic guarantee of payment.

Anvil enables transparency and trustless verification of assets, thereby reducing counterparty risk. The protocol is designed for maximum efficiency and extensibility to incorporate collateral throughout decentralized and traditional finance.

#### What can Anvil be used for?

Anvil is a unified protocol for asset provision, designed explicitly for safety, simplicity, and composability as a primitive building block in the development of other applications.

**Payments**: LOCs offer security for both online and in-store digital payment transactions.

**Counterparty credit**: LOCs can be accepted on centralized exchanges to secure instant deposits for immediate trading or more efficient liquidity provision.

**Asset bridging**: LOCs can facilitate immediate cross-platform transactions. LOCs can also secure deposit or withdrawal transactions on layer 2 (L2) implementations. In instances where a platform integrates Anvil LOCs, immediate, on-demand asset transfers can be safely executed.

Anvil incorporates the governance model pioneered by [<mark style="color:blue;">Compound Labs</mark>](https://docs.compound.finance/governance/) and [<mark style="color:blue;">Open Zeppelin</mark>](https://docs.openzeppelin.com/contracts/4.x/api/governance), with all protocol operations governed by the ANVL token.


# Repository

Contract code, descriptions, deployed addresses, and build instructions are publicly available on the Acronym Foundation's [Github](https://github.com/AcronymFoundation/anvil-contracts). In addition, our contracts have been verified and are available to view on Etherscan.


# Audits

## **OpenZeppelin Audit # 1**

<https://blog.openzeppelin.com/anvil-audit>

## **OpenZeppelin Audit # 2**

<https://blog.openzeppelin.com/anvil-protocol-audit>

## **Trail Of Bits Audit**

<https://github.com/trailofbits/publications/blob/master/reviews/2023-12-acronym-foundation-securityreview.pdf>


# Collateral Vault

{% tabs %}
{% tab title="Overview" %}

## Overview

The Collateral Vault is the central place where collateral tokens and account balances are stored. It serves as the primary financial entry and exit point for the ecosystem, allowing users to deposit, transfer, and withdraw their collateral. In addition to being a storage mechanism, the vault is where collateral is housed for utilization throughout the protocol. Other protocol connected smart contracts, known as Collateralizable Contracts, are able to create reservations of collateral on users’ behalf. These reservation records are stored in the Collateral Vault and ensure that protocol users can leverage their collateral from a central and secure location. Collateralizable Contracts must be first approved by Anvil’s Governance, and can only leverage users’ collateral with their authorization.
{% endtab %}

{% tab title="Vault Data" %}

## Vault Data

### Account Balances

The Collateral Vault stores a ledger of all collateral associated with an account. This association is made by mapping the account to each collateral token and then to their balance breakdown. This account balance includes the available balance amount as well as the amount that is currently reserved (*see:* Collateral Reservations). Accounts may be Externally Owned Accounts (EOAs), external smart contracts unknown to the protocol (treated the same as EOAs for permissioning), or approved Collateralizable Contracts.

### Collateral Reservations

While account balances store the total token amounts associated with an account, it is left to the Collateral Vault’s collateral reservations to track how much of those balances are being utilized as collateral elsewhere in the protocol. Vault reservations are utilized to secure collateral for the purpose of guaranteeing LOCs as well as staked funds in collateral pools. Any collateral that is being reserved cannot be withdrawn from the vault or used in another reservation. Reservations are created and modified by other Collateralizable Contracts via the ICollateral interface. A reservation consists of an id (set by the vault’s `collateralReservationNonce`), the account reserving the collateral, the token and amount to be reserved, and the Collateralizable Contract that manages the reservation. In addition, the collateral reservation contains a memorialization of the withdrawal fee in basis points as well as the claimable token amount (token amount minus the amount to be assessed as a fee).

### Collateral Tokens

The Collateral Vault stores the mapping of `collateralTokens` to total vault token balance as well as whether the token is currently enabled for usage as collateral. An `enabled` token is eligible for depositing into the vault and staking into collateral pools. For a token to be effectively supported by the protocol, it should conform to the ERC-20 standard. In addition, token enablement/disablement is subject to Governance approval. If Governance decides to disable a previously supported token, existing collateral can still be claimed, unstaked, and released from collateral pools, used in existing LOCs (*see:* Letter Of Credit), and withdrawn from the vault.

### Collateralizable Contracts

For smart contracts to be able to interact with the Collateral Vault, it must do so via its ICollateral interface. Only Governance approved contract addresses may interact with the vault through its interface functionality. To manage this, the vault’s contract state stores `collateralizableContracts` where the external contract addresses are mapped to their boolean approval status. Similarly to collateral tokens, when previously `approved` Collateralizable Contracts become disapproved, they enter a decrease-only state whereby the collateral reservations can no longer be created or increased. In the case of collateral pools, this means pool participants can still unstake and release their collateral as well as have their collateral claimed.

In addition, the Collateral Vault stores a mapping of each account’s token transfer approval amounts per Collateralizable Contract. This is a security measure in line with typical ERC-20 transfer allowances. This allows protocol users to be explicit about transfer allowances from within the protocol.\\

### Protocol Fee

The protocol only has one built-in mechanism for assessing fees to its users and that is upon the withdrawal of collateral from the Collateral Vault. This can occur when a user withdraws an available balance from the vault to their wallet, a LOC gets converted/redeemed, or a pool’s collateral gets claimed. The fee setting is housed as `withdrawalFeeBasisPoints` within the `CollateralVault` contract and it is memorialized in each collateral reservation at the time of creation. Fees are retained in the Collateral Vault in the form of a delta between the token balances of the contract and the cumulative account balances. Governance can transfer the amassed fees to a destination of its choosing.

As of Anvil’s launch, the protocol currently has its withdrawal fee initialized to 0. However, this is subject to change by Governance so it is important to always read the latest withdrawal fee from the Collateral Vault contract and any relevant collateral reservations. \\

### Permitted Collateral Upgrade Contracts

A stored mapping of Collateral Vault addresses to whether they are `enabled`. When an address is set to `true`, users can move collateral between vaults through the ICollateralDepositTargets interface. This is vital to Collateral Vault upgradeability.
{% endtab %}

{% tab title="Functionality" %}

## Functionality

### General Functions

#### Functions List

| **Function Name**                                        | **Description**                                                                                                                                                                                                                                                                                                                                    |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Read Functions                                           | <p><br></p>                                                                                                                                                                                                                                                                                                                                        |
| `getCollateralToken(...)`                                | Gets a collateral token’s `enabled` status when provided with a token address.                                                                                                                                                                                                                                                                     |
| `getAccountCollateralBalance(...)`                       | Gets the token available and reserved balances of an account when provided with an account address and a token address.                                                                                                                                                                                                                            |
| `getCollateralReservation(...)`                          | Gets details of a collateral reservation when provided with the reservation id.                                                                                                                                                                                                                                                                    |
| `getClaimableAmount(...)`                                | Gets the claimable amount when provided with a collateral reservation id.                                                                                                                                                                                                                                                                          |
| `getCollateralizableTokenAllowance(...)`                 | Gets the token allowance when provided with an account address, a Collateralizable Contract address, and a token address.                                                                                                                                                                                                                          |
| `getWithdrawalFeeBasisPoints(...)`                       | <p>Gets the current protocol withdrawal fee in basis points.</p><p><em>Note: Collateral reservations may be subject to a different previously captured withdrawal fee value from the time of creation.</em></p>                                                                                                                                    |
| `supportsInterface(...)`                                 | Gets whether the Collateral Vault supports an interface given the interface id.                                                                                                                                                                                                                                                                    |
| Write Functions                                          | <p><br></p>                                                                                                                                                                                                                                                                                                                                        |
| `claimCollateral(...)`                                   | Claims some or all of the collateral of a reservation to a provided address. Used by pool claimants and LOC beneficiaries.                                                                                                                                                                                                                         |
| `depositAndApprove(...)`                                 | Allows a Collateralizable Contract to handle both token allowance approval and `depositToAccount(...)` steps in the same call since they are both necessary to accomplish a deposit.                                                                                                                                                               |
| `depositFromAccount(...)`                                | Used by Time Based Collateral Pool for its `depositAndStake(...)` function whereby the pool can have a users’ collateral transferred into its vault account and then added to a collateral reservation for staking provided it has user authorization.                                                                                             |
| `depositToAccount(...)`                                  | Allows users to deposit collateral into the vault as well as allows for other calling vaults to transfer user collateral via the ICollateralDepositTarget interface in the case of vault upgrades.                                                                                                                                                 |
| `modifyCollateralizableTokenAllowance(...)`              | Used by Collateralizable Contracts to modify the contracts token allowance from the user provided the contract address, token address, and the amount (positive or negative) by which the allowance will be modified.                                                                                                                              |
| `modifyCollateralizableTokenAllowanceWithSignature(...)` | Same as `modifyCollateralizableTokenAllowance(...)` above but more explicit whereby the user signs the data to process the allowance change including the Collateralizable Contract address which the allowance modification is targeting. This is used by Letter Of Credit and Time Based Collateral Pool.                                        |
| `modifyCollateralReservation(...)`                       | Allows a Collateralizable Contract to modify a collateral reservation when provided with the reservation id and the (positive or negative) amount to change. This function is utilized by Letter Of Credit when a user modifies their LOC’s collateral and by Time Based Collateral Pool for staking and unstaking.                                |
| `poolCollateral(...)`                                    | Called by Time Based Collateral Pool when a user stakes collateral from their vault account into a pool instance. This transfers the provided token and amount from the users account to the pool instance’s account within the vault.                                                                                                             |
| `releaseAllCollateral(...)`                              | Collateralizable Contracts call this function to remove a collateral reservation and adjust the account’s available and reserved balances accordingly. This is utilized by Letter Of Credit when a LOC is canceled and by Time Based Collateral Pool when a pool instance is reset.                                                                |
| `reserveClaimableCollateral(...)`                        | Creates a collateral reservation when provided with the reserving account, token, and the amount that should be claimable. The function will then calculate the full reservation amount to be reserved with the fee.                                                                                                                               |
| `reserveCollateral(...)`                                 | Similar to `reserveClaimableCollateral(...)`. Creates a collateral reservation when provided with the reserving account, token, and the total amount to be reserved. The function will calculate the claimable amount after deducting the fee.                                                                                                     |
| `transferCollateral(...)`                                | Transfers available collateral from one vault account to another when provided with the origin address, destination address, token and amount. This transfer will not incur a fee. This function is also leveraged by Time Based Collateral Pool when moving a pool participant’s funds into the pool instance account for the purpose of staking. |
| `upgradeAccount(...)`                                    | Moves the user’s collateral from the current vault to a new approved collateral vault (*see:* Permitted Collateral Upgrade Contracts) that has implemented the ICollateralDepositTarget interface. Accepts multiple pairings of tokens and their amounts to be moved. Can only be done by the account sender.                                      |
| `withdraw(...)`                                          | Withdraws sender’s funds from the vault to an external address when provided with the token, amount, and destination. The current protocol withdrawal fee will be subtracted from the withdrawal amount.                                                                                                                                           |

### Governance

These are functions that can only be performed via the execution of a successful Governance proposal (*see:* Proposal Process). They are decorated in the published contract code with the `onlyOwner` modifier.

#### Function List

| **Function Name**                              | **Description**                                                                                                                                                                                                                       |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upsertCollateralizableContractApprovals(...)` | Updates the approval status of one or more Collateralizable Contracts. Used when upgrading contracts, expanding the protocol, adding new Time Based Collateral Pool instances (proxies), and removing support for existing contracts. |
| ​​`upsertCollateralTokens(...)`                | Updates the status of collateral tokens that are approved for use. Used when adding new token support and removing support for existing tokens.                                                                                       |
| `upsertCollateralUpgradeContractApproval(...)` | Updates the approval status of a ICollateralDepositTarget contract that may be sent an account's available collateral upon the account’s request. Used when upgrading to a new Collateral Vault contract.                             |
| `withdrawFromProtocolBalance(...)`             | Withdraws unaccounted for token balances to a desired address. Used to send amassed protocol fees and errant token transfers to the destination of Governance’s choice.                                                               |

### Interfaces

#### ICollateral

Functionality to be used by approved Collateralizable Contracts when interacting on users’ behalf. These functions deal with reading vault settings, performing CRUD operations on collateral reservations, and modifying token allowances.

**Supported Functions**

Read Functions

`getCollateralToken(...)`

`getAccountCollateralBalance(...)`

`getCollateralReservation(...)`

`getClaimableAmount(...)`

`getCollateralizableTokenAllowance(...)`

`getWithdrawalFeeBasisPoints(...)`

\
Write Functions

`claimCollateral(...)`

`depositFromAccount(...)`

`modifyCollateralizableTokenAllowance(...)`

`modifyCollateralizableTokenAllowanceWithSignature(...)`

`modifyCollateralReservation(...)`

`poolCollateral(...)`

`releaseAllCollateral(...)`

`reserveClaimableCollateral(...)`

`reserveCollateral(...)`

`transferCollateral(...)`

`withdraw(...)`

\\

#### ICollateralDepositTarget

Interface with only one function allowing the deposit of assets into a new ICollateral contract for benefit of a specified account.

**Supported Functions**

`depositToAccount(...)`

\\
{% endtab %}
{% endtabs %}


# Time Based Collateral Pool

The time based collateral pool (TBCP) enables assets from multiple accounts to be collectively pooled for mutual collateral reservations. Third parties may configure and deploy instances of the TBCP contract as required for intended credit operations.

Accounts provide assets to a collateral pool and receive pool units proportional to its total balance. Pool units are associated with each account. To ensure predictable and efficient pool withdrawals, collateral is subject to time-based exit periods.


# Letter of credits

## LOC

A Letter of Credit (LOC) is a contractual agreement that guarantees payment on time and in full from a buyer (creator) to a seller (beneficiary).

The Anvil LOC comprises two elements: the collateral asset, which secures the LOC, and the credited asset, representing its redeemable value. The protocol supports LOC issuance irrespective of the collateral and credit asset types.

The critical aspect of every LOC is the redeemability of its full credited value. To mitigate potential market volatility all LOCs require sufficient overcollateralization. Liquidity must be available for collateral-asset-to-credited-asset conversion, guaranteeing beneficiaries invariably receive the credited asset.

## Create

A user deposits collateral assets (e.g., WETH or USDT) into the Anvil vault contract in order to create a LOC for a credited asset amount (i.e., the LOC value). The protocol supports LOCs issued by distinct accounts as well as multi-party stake pools.

## Extend

Individual LOCs expire at a specified time but are extendable by the creator indefinitely; pool-based LOCs are designed for perpetual duration with time-delayed withdrawals.

## Redeem or Cancel

A LOC can only be redeemed or canceled by the designated beneficiary address. Alternatively, the beneficiary may generate a cancel or redeem signature to allow a third party to expire the LOC or accept the credited assets at the specified recipient address. This account can be a smart contract solely responsible for generating gasless signatures, authorizing transfers to separate accounts.

## Modify

The prevailing exchange rate between the collateral and credited assets can fluctuate significantly. The LOC creator may be inclined to supply additional collateral to mitigate conversion risk or withdraw collateral for more efficient asset utilization.

## Convert

To provide the credited asset upon a redeem request, the protocol allows a LOC to be converted, whereby collateral assets are exchanged for proportionate credited assets. Conversions are implemented in a method consistent with liquidation processes of prevailing money market platforms.

A primary feature of the protocol is that beneficiaries never acquire or possess the underlying collateral; if a LOC is redeemed, credited assets are transferred directly to the recipient address.


# Governance

Anvil has adopted the OpenZeppelin Governor contracts to manage `CollateralVault`, `TimeBasedCollateralPool`, and `LetterOfCredit` contracts. All contracts have configurable parameters, allowing prudential adjustments as additional market data becomes available to ensure protocol safety.

The Anvil protocol is governed by the community of ANVL holders and delegates. On-Chain governance allows the community to propose, vote on, and implement changes to the configurable parameters of the Anvil protocol contracts. This framework ensures that the protocol parameters (e.g. token support, limits, and collateral factors) are determined and supported by decentralized governance.


# Proposal Process

## Introduction

Anvil governance is a 100% on-chain autonomous process: ANVL token holders vote on proposals submitted as code to update the Anvil protocol. The entire on-chain process occurs over two weeks without needing a trusted intermediary.

## Delegating tokens

To participate in Anvil governance, ANVL token holders must first delegate their tokens for voting. For more information on ANVL token delegation, please see the Delegation section.

<figure><img src="https://1877993407-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRYZqahnNqgZ87jrz4qsR%2Fuploads%2FjlvtD45GiyqAjISywkI2%2FScreenshot%202024-06-15%20at%209.10.16%E2%80%AFAM.png?alt=media&#x26;token=024cd527-e98b-4c5c-9fff-5c115c8cc070" alt=""><figcaption><p>Anvil Proposal Process</p></figcaption></figure>

#### Proposal threshold

At least 500 million total ANVL votes are required to submit a proposal to governance. Delegation of the minimum threshold can be self-delegated or delegated by others.

#### Voting delay

The voting delay is 2 days. This provides ANVL holders time to delegate their tokens (if they have not done so already) or re-delegate to a new address. It also serves as an opportunity to review and discuss the submitted proposal in the forum.

#### Voting period

The voting period is 5 days. ANVL holders who have delegated their tokens can vote `for`, `abstain`, or `against` proposals during the voting period. Proposals require at least five billion ANVL total votes `for` or `abstain` to reach quorum.

#### Proposal failure

At the end of the voting period, proposals that do not reach quorum or reach quorum but receive more `against` votes than `for` votes are not executed.

#### Proposal success

Any proposal that reaches a quorum requires more `for` than `against` votes at the end of the voting period to pass. Any account may queue passed proposals in the execution timelock.

#### Timelock

For successful proposals, there is a 7-day timelock to provide all protocol users time to understand the new parameters and their implications prior to the update. At the end of the 7-day timelock, any account may execute the proposal, triggering its code to be executed on-chain.

\\


# Delegation

### *What is delegation?*

The Anvil protocol uses a governor contract that requires the delegation of ANVL tokens to participate in on-chain governance. Delegating your ANVL tokens can be done at[ ](https://app.anvil.xyz)<https://app.anvil.xyz/governance>.

### &#x20;*Who can I delegate to?*

You may delegate to yourself or third-parties. If you delegate to another account, you still maintain ownership of your tokens, but the votes the specified delegate casts will have the additional weight of your tokens until you re-delegate your ANVL. You may revoke your delegation choice by re-delegating at any time.

### *Why do I need to delegate?*

Delegation allows your tokens to be used to vote in on-chain proposals. Anvil is decentralized, so the diversity and number of ANVL delegates bolster the protocol.

### *Why does delegation cost ETH?*

Delegation costs ETH because you are writing your delegation to the Ethereum blockchain. The ETH you are paying is the gas fee for that transaction. A gasless delegation option exists whereby token holders may create an off-chain signature that allows any motivated account to execute their delegation preference on chain (see the `delegateBySig` function of the [ANVL token contract](https://etherscan.io/token/0x2Ca9242c1810029Efed539F1c60D68B63AD01BFc#writeContract)).

\\


# Whitepaper

{% file src="/files/wKPMFTLdUxF1XiSslv4j" %}


# Social media

#### Official contacts and social networks anvilproject:

{% hint style="success" %}
**Telegram:** [**https:/t.me/anvilproject**](https://t.me/anvilproject)
{% endhint %}

{% hint style="success" %}
**Website:** [**https:/anvilapplication.com**](https://anvilapplication.com/)
{% endhint %}

Official Telegram accounts of Anvil employees:

{% hint style="success" %}
**Acronym:** [@head\_anvil](https://t.me/head_anvil)
{% endhint %}

{% hint style="success" %}
**Noah:** [@Noah\_Anvil](https://t.me/noah_anvil)
{% endhint %}

{% hint style="success" %}
**Liu:** [@Liu\_anvil](https://t.me/Liu_anvil)
{% endhint %}

{% hint style="success" %}
**Annie:** [@Annie\_Anvil](https://t.me/annie_anvil)
{% endhint %}

Please ignore all messages from strangers claiming to be Anvil employees. The official contact details are listed above, always check them!


