Proposal Date
2026-08-13
Relevant Contracts
LetterOfCredit Proxy: 0x14db9a91933aD9433E1A0dB04D08e5D9EF7c4808
LetterOfCredit Proxy Admin: 0x12225bB169b38EF8849DD4F5Cc466ae5996e341D
Proposed LetterOfCredit Singleton: 0x6c22beA8930980C6C5B4f9c449DA0964eDCAa33B
PythPriceOracle: 0xC6f3405c861Fa0dca04EC4BA59Bc189D1d56Ee05
Overview
Now that the protocol’s Letter Of Credit system has been utilized for a significant period of time, it is warranted to re-examine the functionality and configurations through the lens of user feedback and the latest market data. The project contributors have been collecting feedback from LOC creators, integrators, and liquidators in addition to refining market analysis and risk frameworks. The resulting output has resulted in this omnibus proposal.
Background
Liquidation Learnings
Globalization of Collateral Factors
Currently, the Governance-set collateral factors that ensure sufficient overcollateralization of dynamic LOCs are stored in the contract state as both global and local (per-LOC basis) variables. When a new LOC is created its health is governed by a memorialized version of the current collateral factor and liquidation incentive. However, this value is version-controlled on the LOC level and is not affected when Governance updates these values globally. This is an intentional design feature but worth re-examining.
The benefit of having LOCs governed by locally stored collateral factors is largely for the LOC creator’s user experience. When a new LOC is created, the issuer knows that there is an unchanging ratio at which their LOC could be subject to liquidation as well as the basis points they stand to lose to cover the liquidator’s incentive. While this may provide peace of mind to the LOC creator regarding the exact parameters of the financial promise they are entering into and may allow them not to care about changes to the protocol while their LOC is active, it does come with some significant risk to the protocol writ large.
The main tradeoffs of this model involved protocol solvency, Governance impact, and liquidator experience. The first two of these go hand in hand: simply put, if LOCs are grandfathered into the collateral factors at their creation, they prevent Governance from fully doing one of its core functions: protecting protocol solvency. While collateral factors may have been responsibly set at the time of the LOCs creation, digital asset markets are not frozen in time and are often subject to overall large, sometimes unprecedented, swings as well as individual token volatility. While Governance can take action to update these collateral factors globally, it does nothing to impact existing LOCs that may have become unhealthy yet remain uncorrectable via liquidation. This is worth addressing now that the protocol has gotten substantially more usage and risk frameworks have been created to monitor these values in real time.
In addition, it is worth considering the experience needed for Governance and liquidators. Governance should be able to protect against changing market conditions on behalf of the entire protocol and not just future LOCs. Also, the most important experience in the dynamic LOC lifecycle is the role of the liquidators. Liquidators play a key role in the solvency of the LOC system and need to be properly incentivized accounting for the latest market competition while experiencing the least development friction and operational complexity possible. A liquidator’s job is made much more difficult by having to monitor every LOC against its specific collateral factor as well as needing to evaluate the benefit of liquidation using LOC-specific incentive values.
The result is the clear need to enable global collateral factors as the only governing parameters regarding LOCs health and liquidator incentive.
Separation of Incentive Values
The process of converting the collateral of a dynamic LOC into its credited form can either be the result of: 1) a permissioned action like a beneficiary redeeming a LOC or 2) a permissionless action taken on an unhealthy LOC (where its collateral factor has been exceeded). Both of these scenarios require providing a “liquidator” (in the form of contract address) to execute, however they result from different motivations and processes. The permissioned conversions are initiated on-demand and by the benefiting party; they do not require extra incentive to be initiated. Conversely, the permissionless conversions are often driven by third-parties watching chain data and initiating conversion when a LOC becomes unhealthy. This requires incentivization and is critical to maintaining protocol solvency.
Despite the different motivations, both scenarios are currently incentivized the same way: a token-pairing specific “liquidation incentive” that acts as a premium paid to the liquidator for processing the conversion. This creates two issues: 1) it might incentivize a beneficiary to redeem LOCs and act as the convertor, thus keeping excess beyond what is required to fulfill the financial promise and 2) it makes the LOC creator less capital efficient by taking more collateral than is actually necessary for redemption.
The solution is to address these paths separately. However, permissioned actions cannot simply provide the liquidation contract without any excess. This is because a portion of the liquidation incentive is used to cover slippage for liquidators that utilize DEXs to execute the conversion. Without any conversion margin, slippage would result in a liquidator either not being solvent to execute the swap or not resulting in a profitable transaction. One of the main goals of the protocol should be to foster a diverse and robust decentralized liquidation environment that encourages redundancy, optionality, and capital efficiency.
Taken together, the proposed upgrade is the addition of a fourth collateral factor used specifically for permissioned on-demand conversions that should be set to the conservative cost of DEX swaps without any significant excess.
Creator Permissioned LOC Conversion
The protocol was created with a nice-to-have feature whereby LOC creators can convert their own LOC at any time. The reasoning behind this functionality was to provide maximum flexibility to the creator regarding how they are collateralized. In most instances, it is not economically advantageous for the LOC creator to be liquidated. As a LOC approaches becoming unhealthy, the creator is able to either bolster their collateral or, alternatively, process the conversion themselves keeping the liquidation incentive versus losing value to a third-party liquidator. While this approach certainly considers the LOC creators experience, it does so at the detriment of the liquidators. As discussed, since the permissionless liquidator’s experience should be paramount, allowing the LOC creator permission to front-run their own inevitable liquidation is counterproductive to the overall protocol’s success and should be removed. This finding has been validated via communications with potential liquidators as well as in research that shows that this concept of permissioned self-liquidation is not common with DeFi protocols.
Integrator Feedback
LOC Maximums
In conversations with integration partners, notably those utilizing the “Promise Now, Pay Later” use case for higher value conference sponsorships, it was learned that the current token configurations for dynamic LOC credited maximums of 100,000 USDC and USDT are insufficient. It is not uncommon for these sponsorships to be in the six figures and it is not preferred to have to split the commitment across multiple LOCs. Increasing these maximums from their initial conservative values at launch is warranted and does not expose the protocol to any undue risk. Note that as the adoption of these LOCs increases, there may be a need to adjust the global maximum of these tokens in the near future.
Metadata Expansion
One of the highlights of Anvil’s adoption with enterprises involves the newly released “institutional beneficiary” tool created by Anvil Research Labs. This enterprise solution maximizes ease of operational integration via, among other things, its customizable display, parsing, and filtering of the metadata “tag” field at LOC creation. The use of this field to memorialize relevant operational data onchain allows businesses to contextualize the LOC’s existence in an easy to leverage way. This field was introduced at the maximum fixed length size (32 bytes) but integrators are requesting additional space. Increasing the potential length of this field by making it dynamic provides much greater flexibility. Since this parameter is only used in the LOC creation event, there is no added cost to protocol users since it is not stored in the contract state.
EURC Support
After receiving this request, ARL was able to confirm that this user is leading the Swiss-based finance startup Helva. Their model is built to offer fiat consumer loans against Anvil LOCs – one of the protocol’s flagship proposed use cases. Since the protocol currently only supports USD-pegged stablecoins as credited values for dynamic LOCs, it creates an extra level of operational complexity for EU based customers. After evaluating EURC as a dynamic credited token against market data and third-party modeling, there emerged reasonable, yet conservative, token configurations and collateral factors that can be implemented to aid in this integration.
Proposed Changes
Described Changes
Implementation Changes
- Changes
_tagparameter oncreateStaticLOC()andcreateDynamicLOC()from typebytes32tobytes calldata- By changing from a fixed 32-byte size to a dynamic length, the amount of metadata that can be appended to a LOC greatly increases.
- Expands
CollateralFactorto include newredeemBufferBasisPointsvalue- Used to differentiate between an amount sent to the liquidator to cover slippage while on demand redeeming vs the cumulative amount sent to cover both slippage and the monitoring incentive.
- When
redeemLOC()is called,redeemBufferBasisPointsvalue is added to the amount sent to the liquidator instead ofliquidatorIncentiveBasisPoints - Utilizes global
liquidatorIncentiveBasisPointswhenconvertLOC()is called via theILiquidatableinterface.- This value is now only used for permissionless liquidations of unhealthy LOCs. For redemptions,
redeemBufferBasisPointsis now used
- This value is now only used for permissionless liquidations of unhealthy LOCs. For redemptions,
- Utilizes global
collateralFactorBasisPointswhen evaluating health of a LOC instead of the value memorialized in the data mapped from the specific LOC id - Removes path whereby a LOC creator can call
convertLOC()on a healthy LOC- This prevents the front-running third-party liquidators so as to keep them economically incentivized
Configuration Changes
- Updates the USDC and USDT token configurations on
CreditedTokento increase themaxPerDynamicLOCto from 100,000 to 250,000- Note: Global maximums and LOC minimums remain the same
- Adds dynamic LOC credit support for EURC, configuring its
CreditedTokenvalues- Values are conservative and third-party risk-assessed yet within the usable range provided by the integrator (Helva Finance)
- Adds
CollateralFactors for every existing dynamic collateral token with EURC as the credited token- These values generated from latest third-party produced model
- Adds the stable EURC/USD Pyth price feed id to the
PythPriceOracleadapter contract- Requirement for dynamic use
Executed Changes
Calls LetterOfCredit Proxy Admin::upgradeAndCall() to set the LetterOfCredit Proxy implementation to 0x6c22beA8930980C6C5B4f9c449DA0964eDCAa33B
Calls LetterOfCredit Proxy::upsertCreditedTokens() to set:
- USDC
maxPerDynamicLOCto250,000.000000
- USDT
maxPerDynamicLOCto250,000.000000
- EURC
minPerDynamicLOCto100.000000maxPerDynamicLOCto30,000.000000globalMaxInDynamicUseto320,000.000000
Calls LetterOfCredit Proxy::upsertCollateralFactors() to set:
| Collateral Token | Credited Token | Creation Collateral Factor | Collateral Factor (Liquidation) | Liquidator Incentive | Redeem Buffer |
|---|---|---|---|---|---|
| cbBTC | EURC | 6127 (61.27%) | 7208 (72.08%) | 800 (8%) | 500 (5%) |
| cbBTC | USDC | 6000 (60%) | 7100 (71%) | 800 (8%) | 500 (5%) |
| cbBTC | USDT | 6000 (60%) | 7100 (71%) | 800 (8%) | 500 (5%) |
| sUSDe | EURC | 6922 (69.22%) | 8143 (81.43%) | 800 (8%) | 500 (5%) |
| sUSDe | USDC | 7100 (71%) | 8300 (83%) | 800 (8%) | 500 (5%) |
| sUSDe | USDT | 7100 (71%) | 8300 (83%) | 800 (8%) | 500 (5%) |
| USDC | EURC | 6774 (67.74%) | 7970 (79.70%) | 800 (8%) | 500 (5%) |
| USDC | USDT | 7100 (71%) | 8300 (83%) | 800 (8%) | 500 (5%) |
| USDC | WETH | 0000 (0%) | 0001 (0.01%) | 800 (8%) | 500 (5%) |
| USDT | EURC | 6754 (67.54%) | 7946 (79.46%) | 800 (8%) | 500 (5%) |
| USDT | USDC | 7100 (71%) | 8300 (83%) | 800 (8%) | 500 (5%) |
| USDT | WETH | 0000 (0%) | 0001 (0.01%) | 800 (8%) | 500 (5%) |
| WBTC | EURC | 6078 (60.78%) | 7151 (71.51%) | 800 (8%) | 500 (5%) |
| WBTC | USDC | 6000 (60%) | 7100 (71%) | 800 (8%) | 500 (5%) |
| WBTC | USDT | 6000 (60%) | 7100 (71%) | 800 (8%) | 500 (5%) |
| WETH | EURC | 5901 (59.01%) | 6943 (69.43%) | 800 (8%) | 500 (5%) |
| WETH | USDC | 5600 (56%) | 6600 (66%) | 800 (8%) | 500 (5%) |
| WETH | USDT | 5600 (56%) | 6600 (66%) | 800 (8%) | 500 (5%) |
| wstETH | EURC | 6037 (60.37%) | 7102 (71.02%) | 800 (8%) | 500 (5%) |
| wstETH | USDC | 5600 (56%) | 6600 (66%) | 800 (8%) | 500 (5%) |
| wstETH | USDT | 5600 (56%) | 6600 (66%) | 800 (8%) | 500 (5%) |
Calls PythPriceOracle::upsertPriceFeedIds() to set EURC to 0x76fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5c