Skip to content
Lattice

CurveStableSwapAdapter

Git Source

Inherits: IStrategy, IProtocolAdapter, IAdapterOperator, ICurveStableSwapAdapter

Title: CurveStableSwapAdapter

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Curve (https://github.com/curvefi/curve-contract)

Diamond facet adapting a single-sided Curve StableSwap LP position into a Lattice vault strategy. Implements IStrategy (funds routing), IProtocolAdapter (sidecar), and ICurveStableSwapAdapter (Curve config). Deposits the configured asset into one side of a 2-coin pool, holds or stakes the LP, and values it via get_virtual_price. CRV rewards are forwarded RAW (swap-free) and excluded from NAV. All logic lives in CurveStableSwapAdapterLib.

Provenance: Curve StableSwap (https://github.com/curvefi/curve-contract) + Curve LiquidityGauge (https://github.com/curvefi/curve-dao-contracts).

UNSUPPORTED in 0.5.0: do not register this adapter with a vault's StrategyManager. A VaultCore vault prices ERC-4626 shares on its full NAV, which includes this adapter's spot get_virtual_price() valuation. That value can be skewed by read-only reentrancy from a pool callback that runs no Lattice code, so it is unsafe as a share-pricing source. Nothing in this release probes the pool for that reentrancy (#221), and addStrategy does not reject the adapter: keeping it out of a vault is the integrator's responsibility. Its single-coin exit fee also makes a rebalance recall lose value, which the StrategyManager rejects beyond its fixed rounding tolerance.

Notes:

  • lattice-version: 0.1.0
  • lattice-source: Lattice original

Functions

asset

Returns the address of the underlying asset this strategy manages.

function asset() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

totalAssetsManaged

Returns the current total asset balance managed by this strategy.

This value is trusted by the StrategyManager and VaultCore for accounting. Strategy implementations MUST report accurate balances to avoid mispricing vault shares.

function totalAssetsManaged() external view virtual override returns (uint256);

Returns

NameTypeDescription
<none>uint256

withdraw

Withdraws amount of the underlying asset to to.

Called by the StrategyManager during rebalancing to recall excess allocations. The strategy is responsible for executing the ERC-20 transfer.

function withdraw(uint256 amount, address to) external virtual override returns (uint256 withdrawn);

Parameters

NameTypeDescription
amountuint256Amount of underlying asset to withdraw.
toaddressRecipient address (typically the vault).

Returns

NameTypeDescription
withdrawnuint256Actual amount transferred (may be less if strategy has slippage).

deploy

Sweeps the adapter's idle asset balance into the external protocol.

Required because the vault PUSHES funds via a bare ERC-20 transfer (no callback). Reverts ProtocolAdapterNothingToDeploy if the idle balance is zero.

function deploy() external virtual override returns (uint256 deployed);

Returns

NameTypeDescription
deployeduint256The amount swept into the protocol.

harvest

Claims reward tokens from the protocol and forwards them RAW (no swap) to the configured recipient.

Safe against zero-claim and fee-on-transfer reward tokens; never reverts withdraw.

function harvest() external virtual override;

emergencyWithdraw

Fully exits the protocol position and returns all recovered assets to the vault.

Intended for the emergency path; callable by an authorized guardian/admin even when the adapter is paused.

function emergencyWithdraw() external virtual override returns (uint256 recovered);

Returns

NameTypeDescription
recovereduint256The amount returned to the vault.

isPaused

Returns true when the adapter is paused or emergency-stopped, or the external protocol reports the asset paused/frozen. When true, deploy() must be a no-op path (revert), so a paused protocol cannot brick rebalance().

function isPaused() external view virtual override returns (bool);

Returns

NameTypeDescription
<none>bool

healthFactor

Returns the current health factor (WAD, 1e18 == 1.0) of the adapter's position.

Supply-only adapters return type(uint256).max (no debt). Leverage adapters return collateralValue * liquidationThreshold / debtValue.

function healthFactor() external view virtual override returns (uint256);

Returns

NameTypeDescription
<none>uint256

minHealthFactor

Returns the configured minimum health factor (WAD) the adapter must not breach.

function minHealthFactor() external view virtual override returns (uint256);

Returns

NameTypeDescription
<none>uint256

rewardRecipient

Returns the address rewards are forwarded to.

function rewardRecipient() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

setOperator

Sets the authorized operator permitted to call deploy/withdraw/harvest.

Admin-gated (DEFAULT_ADMIN_ROLE). Rejects address(0); emits IProtocolAdapter.OperatorSet.

function setOperator(address operator_) external virtual override;

Parameters

NameTypeDescription
operator_addressThe new operator (typically the StrategyManager diamond).

operator

Returns the authorized operator (zero until wired).

function operator() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

reentrancyGuardEntered

True while a guarded op is executing — mirrors StrategyManager so VaultCore can reject share-price-sensitive ops mid-deploy/withdraw (read-only reentrancy guard).

function reentrancyGuardEntered() external view virtual returns (bool);

Returns

NameTypeDescription
<none>bool

pool

Returns the Curve StableSwap pool this adapter supplies to.

function pool() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

lpToken

Returns the pool's LP token.

function lpToken() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

gauge

Returns the staking gauge (address(0) when the adapter holds LP unstaked).

function gauge() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

crvToken

Returns the CRV (primary gauge reward) token forwarded raw on harvest (address(0) == none).

function crvToken() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

vault

Returns the Lattice vault funds are returned to.

function vault() external view virtual override returns (address);

Returns

NameTypeDescription
<none>address

coinIndex

Returns the pool coin index the adapter's asset occupies.

function coinIndex() external view virtual override returns (int128);

Returns

NameTypeDescription
<none>int128

slippageBps

Returns the configured slippage tolerance in basis points.

function slippageBps() external view virtual override returns (uint256);

Returns

NameTypeDescription
<none>uint256

setGauge

Sets the staking gauge (admin only). address(0) clears it (run unstaked). Setting a new gauge does not migrate existing LP; stake/unstake happens on the next deploy/withdraw.

function setGauge(address gauge_) external virtual override;

Parameters

NameTypeDescription
gauge_address

setCrvToken

Sets the CRV reward token forwarded raw on harvest (admin only). address(0) skips forwarding (claim only). Decoupled from the gauge so integrators can wire the deployment's canonical CRV address (or clear it) without re-deploying the facet.

function setCrvToken(address token) external virtual override;

Parameters

NameTypeDescription
tokenaddress

setSlippageBps

Sets the slippage tolerance in basis points (admin only).

function setSlippageBps(uint256 slippageBps_) external virtual override;

Parameters

NameTypeDescription
slippageBps_uint256

setRewardRecipient

Sets the reward recipient (admin only).

function setRewardRecipient(address recipient) external virtual override;

Parameters

NameTypeDescription
recipientaddress

exportSelectors

ERC-8153 selector export: this facet's cuttable selectors, tightly packed (4 bytes each).

Excludes exportSelectors() itself (0x0ef22643) - it is never cut into a diamond. Order matches forge inspect CurveStableSwapAdapter methodIdentifiers (alphabetical by signature); kept in exact parity by ExportSelectorsParityTest. Chunks: asset() 0x38d52e0f coinIndex() 0x2604772c crvToken() 0x32d7d66d deploy() 0x775c300c emergencyWithdraw() 0xdb2e21bc gauge() 0xa6f19c84 harvest() 0x4641257d healthFactor() 0x22841f01 isPaused() 0xb187bd26 lpToken() 0x5fcbd285 minHealthFactor() 0xe1b4264c operator() 0x570ca735 pool() 0x16f0115b reentrancyGuardEntered() 0xd2c725e0 rewardRecipient() 0x17f33340 setCrvToken(address) 0x07ec4de0 setGauge(address) 0x55a68ed3 setOperator(address) 0xb3ab15fb setRewardRecipient(address) 0xe521136f setSlippageBps(uint256) 0x1a3ce4e6 slippageBps() 0x578c71d9 totalAssetsManaged() 0x613c822b vault() 0xfbfa77cf withdraw(uint256,address) 0x00f714ce

function exportSelectors() external pure virtual returns (bytes memory selectors);

Returns

NameTypeDescription
selectorsbytes