InvarCoin
Inherits: ERC20, ERC20Permit, Ownable2Step, Pausable, ReentrancyGuard
Title: InvarCoin (INVAR)
Global purchasing power token backed 50/50 by USDC + plDXY-BEAR via Curve LP.
INVAR is a vault token whose backing is held as Curve USDC/plDXY-BEAR LP tokens. Users deposit USDC, which is single-sided deployed to Curve. The vault earns Curve trading fee yield (virtual price growth), which is harvested and donated to sINVAR stakers. LP tokens are valued with dual pricing to prevent manipulation:
- totalAssets() and harvest use pessimistic pricing (min of EMA, oracle) for conservative NAV.
- totalAssetsValidated() provides strict oracle-validated NAV (reverts on stale/invalid oracle).
- deposit() uses optimistic NAV (max of EMA, oracle) so new depositors cannot dilute existing holders.
- lpDeposit() values minted LP pessimistically so depositors cannot extract value from stale-high EMA.
- withdraw() and lpWithdraw() use pro-rata asset distribution (no NAV pricing needed). The oracle-derived LP price mirrors the twocrypto-ng formula: 2 * virtualPrice * sqrt(bearPrice). A 2% USDC buffer (BUFFER_TARGET_BPS) is maintained locally for gas-efficient withdrawals. Excess USDC is deployed to Curve via permissionless keeper calls (deployToCurve). Virtual shares (1e18 INVAR / 1e6 USDC) protect against inflation attacks on the first deposit.
Note: security-contact: contact@plether.com
Constants
USDC
USDC collateral token (6 decimals).
IERC20 public immutable USDC
BEAR
plDXY-BEAR synthetic token (18 decimals).
IERC20 public immutable BEAR
CURVE_LP_TOKEN
Curve USDC/plDXY-BEAR LP token.
IERC20 public immutable CURVE_LP_TOKEN
CURVE_POOL
Curve twocrypto-ng pool for USDC/plDXY-BEAR.
ICurveTwocrypto public immutable CURVE_POOL
BASKET_ORACLE
Chainlink BasketOracle — weighted basket of 6 FX feeds, returns foreign currencies priced in USD (8 decimals).
AggregatorV3Interface public immutable BASKET_ORACLE
SEQUENCER_UPTIME_FEED
L2 sequencer uptime feed for staleness protection (address(0) on L1).
AggregatorV3Interface public immutable SEQUENCER_UPTIME_FEED
CRV_MINTER
Curve Minter for CRV emissions on L1 (address(0) on L2 where claim_rewards handles CRV).
ICurveMinter public immutable CRV_MINTER
BUFFER_TARGET_BPS
uint256 public constant BUFFER_TARGET_BPS = 200
DEPLOY_THRESHOLD
uint256 public constant DEPLOY_THRESHOLD = 1000e6
MAX_SPOT_DEVIATION_BPS
uint256 public constant MAX_SPOT_DEVIATION_BPS = 50
ORACLE_TIMEOUT
uint256 public constant ORACLE_TIMEOUT = 24 hours
SEQUENCER_GRACE_PERIOD
uint256 public constant SEQUENCER_GRACE_PERIOD = 1 hours
VIRTUAL_SHARES
uint256 public constant VIRTUAL_SHARES = 1e18
VIRTUAL_ASSETS
uint256 public constant VIRTUAL_ASSETS = 1e6
USDC_INDEX
uint256 private constant USDC_INDEX = 0
BPS
uint256 private constant BPS = 10_000
STAKED_INVAR_TIMELOCK
uint256 public constant STAKED_INVAR_TIMELOCK = 7 days
GAUGE_TIMELOCK
uint256 public constant GAUGE_TIMELOCK = 7 days
GAUGE_REWARDS_TIMELOCK
uint256 public constant GAUGE_REWARDS_TIMELOCK = 7 days
State Variables
stakedInvarCoin
sINVAR staking contract that receives harvested yield.
StakedToken public stakedInvarCoin
pendingStakedInvarCoin
address public pendingStakedInvarCoin
stakedInvarCoinActivationTime
uint256 public stakedInvarCoinActivationTime
curveLpCostVp
Cumulative virtual-price cost basis of tracked LP tokens (18 decimals).
Used to isolate fee yield (VP growth) from price appreciation. Only LP tokens deployed by the vault are tracked — donated LP is excluded to prevent yield manipulation.
uint256 public curveLpCostVp
trackedLpBalance
LP token balance deployed by the vault (excludes donated LP).
uint256 public trackedLpBalance
emergencyActive
True when emergency mode is active — blocks deposits and single-sided withdrawals.
bool public emergencyActive
curveGauge
ICurveGauge public curveGauge
gaugeStakedLp
Internally-tracked LP balance staked in the gauge (avoids external balanceOf dependency).
uint256 public gaugeStakedLp
pendingGauge
address public pendingGauge
gaugeActivationTime
uint256 public gaugeActivationTime
approvedGauges
mapping(address => bool) public approvedGauges
gaugeRewardsReceiver
address public gaugeRewardsReceiver
pendingGaugeRewardsReceiver
address public pendingGaugeRewardsReceiver
gaugeRewardsReceiverActivationTime
uint256 public gaugeRewardsReceiverActivationTime
protectedRewardTokens
mapping(address => bool) public protectedRewardTokens
Functions
constructor
constructor(
address _usdc,
address _bear,
address _curveLpToken,
address _curvePool,
address _oracle,
address _sequencerUptimeFeed,
address _crvMinter
) ERC20("InvarCoin", "INVAR") ERC20Permit("InvarCoin") Ownable(msg.sender);
Parameters
| Name | Type | Description |
|---|---|---|
_usdc | address | USDC token address. |
_bear | address | plDXY-BEAR token address. |
_curveLpToken | address | Curve USDC/plDXY-BEAR LP token address. |
_curvePool | address | Curve twocrypto-ng pool address. |
_oracle | address | BasketOracle address (Chainlink AggregatorV3Interface). |
_sequencerUptimeFeed | address | L2 sequencer uptime feed (address(0) on L1). |
_crvMinter | address | Curve Minter for CRV emissions (address(0) on L2). |
_validateStakingVault
function _validateStakingVault(
address stakingVault
) private view;
proposeStakedInvarCoin
Propose the sINVAR staking contract. Finalized after STAKED_INVAR_TIMELOCK.
function proposeStakedInvarCoin(
address _stakedInvarCoin
) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
_stakedInvarCoin | address | Address of the StakedToken (sINVAR) contract. |
finalizeStakedInvarCoin
Finalize the proposed sINVAR staking contract after the timelock.
function finalizeStakedInvarCoin() external onlyOwner;
proposeGaugeRewardsReceiver
Propose the receiver for protected gauge reward tokens.
function proposeGaugeRewardsReceiver(
address receiver
) external onlyOwner;
finalizeGaugeRewardsReceiver
Finalize the protected reward receiver after the timelock.
function finalizeGaugeRewardsReceiver() external onlyOwner;
protectRewardToken
Irreversibly marks a token as a protected gauge reward token.
function protectRewardToken(
address token
) external onlyOwner;
sweepGaugeRewards
Sweeps a protected gauge reward token to the configured receiver.
function sweepGaugeRewards(
address token
) external onlyOwner;
totalAssets
Total assets backing INVAR (USDC, 6 decimals).
Uses pessimistic LP pricing: min(Curve EMA, oracle-derived) to prevent stale-EMA exploitation.
function totalAssets() public view returns (uint256);
totalAssetsValidated
Total assets backing INVAR with strict oracle validation (USDC, 6 decimals).
Reverts if sequencer/oracle checks fail (stale, invalid, or within sequencer grace period).
function totalAssetsValidated() external view returns (uint256);
_totalAssetsWithPrice
Total assets using pre-fetched LP balance and validated oracle price.
function _totalAssetsWithPrice(
uint256 lpBal,
uint256 oraclePrice
) private view returns (uint256);
getBufferMetrics
Buffer health metrics for keeper bots and frontends.
Uses permissive totalAssets() (best-effort oracle read). For strict oracle-validated NAV, use totalAssetsValidated().
function getBufferMetrics()
external
view
returns (uint256 currentBuffer, uint256 targetBuffer, uint256 deployable, uint256 replenishable);
Returns
| Name | Type | Description |
|---|---|---|
currentBuffer | uint256 | USDC held locally (6 decimals). |
targetBuffer | uint256 | Target USDC buffer based on total assets (6 decimals). |
deployable | uint256 | Excess USDC deployable to Curve (0 if below threshold). |
replenishable | uint256 | USDC deficit that needs replenishing from Curve LP. |
getHarvestableYield
Estimated harvestable Curve fee yield (USDC, 6 decimals).
Read-only estimator mirroring _harvest math. Uses permissive oracle reads and returns 0 if no staking contract or no VP growth.
function getHarvestableYield() external view returns (uint256 yieldUsdc);
getSpotDeviation
Spot-vs-EMA deviation for a 1 USDC deposit (basis points).
Returns 0 if spot >= EMA (no discount). Used by keepers to check if deploy/replenish is safe.
function getSpotDeviation() external view returns (uint256 deviationBps);
_totalAssetsOptimistic
Total assets using optimistic LP pricing — max(EMA, oracle) to prevent deposit dilution.
function _totalAssetsOptimistic(
uint256 oraclePrice
) private view returns (uint256);
_oracleLpPrice
Oracle-derived LP price: mirrors twocrypto-ng formula 2 * vp * sqrt(bearPrice_18dec).
function _oracleLpPrice(
uint256 oraclePrice
) private view returns (uint256);
_pessimisticLpPrice
function _pessimisticLpPrice(
uint256 oraclePrice
) private view returns (uint256);
_optimisticLpPrice
function _optimisticLpPrice(
uint256 oraclePrice
) private view returns (uint256);
_validatedOraclePrice
function _validatedOraclePrice() private view returns (uint256);
_lpBalance
Total LP held: local + gauge-staked (internally tracked to avoid external call dependency).
function _lpBalance() private view returns (uint256);
_ensureUnstakedLp
Unstakes LP from gauge if local balance is insufficient for the requested amount.
function _ensureUnstakedLp(
uint256 amount
) private;
_reduceLpAccounting
function _reduceLpAccounting(
uint256 lpReduced,
uint256 totalLp
) private;
_recordLpDeployment
function _recordLpDeployment(
uint256 lpMinted
) private;
_stakeLpToGauge
function _stakeLpToGauge(
uint256 amount
) private;
_validateGaugeAddress
function _validateGaugeAddress(
address gauge
) private view;
_validateGauge
function _validateGauge(
address gauge
) private view;
deposit
Deposit USDC to mint INVAR shares. USDC stays in the local buffer until deployed to Curve.
Uses optimistic LP pricing for NAV to prevent deposit dilution. Harvests yield before minting. Reverts while emergencyActive is true.
function deposit(
uint256 usdcAmount,
address receiver,
uint256 minSharesOut
) public nonReentrant whenNotPaused returns (uint256 glUsdMinted);
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | Amount of USDC to deposit (6 decimals). |
receiver | address | Address that receives the minted INVAR shares. |
minSharesOut | uint256 | Minimum INVAR shares to receive (0 = no minimum). |
Returns
| Name | Type | Description |
|---|---|---|
glUsdMinted | uint256 | Number of INVAR shares minted. |
depositWithPermit
Gasless deposit using ERC-2612 permit. Falls back to existing allowance if permit fails (e.g., front-run griefing) and the allowance is sufficient.
function depositWithPermit(
uint256 usdcAmount,
address receiver,
uint256 minSharesOut,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | Amount of USDC to deposit (6 decimals). |
receiver | address | Address that receives the minted INVAR shares. |
minSharesOut | uint256 | Minimum INVAR shares to receive (0 = no minimum). |
deadline | uint256 | Permit signature expiry timestamp. |
v | uint8 | ECDSA recovery byte. |
r | bytes32 | ECDSA r component. |
s | bytes32 | ECDSA s component. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Number of INVAR shares minted. |
withdraw
USDC-only withdrawal via pro-rata buffer + JIT Curve LP burn.
Burns the user’s pro-rata share of local USDC and Curve LP (single-sided to USDC). Does not distribute raw BEAR balances — if the contract holds material BEAR, use lpWithdraw() or set minUsdcOut to enforce fair value. Blocked during emergencyActive since single-sided LP exit may be unavailable.
function withdraw(
uint256 glUsdAmount,
address receiver,
uint256 minUsdcOut
) external nonReentrant whenNotPaused returns (uint256 usdcOut);
Parameters
| Name | Type | Description |
|---|---|---|
glUsdAmount | uint256 | Amount of INVAR shares to burn. |
receiver | address | Address that receives the withdrawn USDC. |
minUsdcOut | uint256 | Minimum USDC to receive (slippage protection). |
Returns
| Name | Type | Description |
|---|---|---|
usdcOut | uint256 | Total USDC returned (buffer + Curve LP proceeds). |
lpWithdraw
Balanced withdrawal: returns pro-rata USDC + BEAR from Curve LP (remove_liquidity).
Intentionally lacks whenNotPaused — serves as the emergency exit when the contract is paused. Emergency mode still honors pro-rata LP claims by redeeming any remaining LP before paying out.
function lpWithdraw(
uint256 glUsdAmount,
uint256 minUsdcOut,
uint256 minBearOut
) external nonReentrant returns (uint256 usdcReturned, uint256 bearReturned);
Parameters
| Name | Type | Description |
|---|---|---|
glUsdAmount | uint256 | Amount of INVAR shares to burn. |
minUsdcOut | uint256 | Minimum USDC to receive (slippage protection). |
minBearOut | uint256 | Minimum plDXY-BEAR to receive (slippage protection). |
Returns
| Name | Type | Description |
|---|---|---|
usdcReturned | uint256 | Total USDC returned. |
bearReturned | uint256 | Total plDXY-BEAR returned. |
_lpWithdraw
function _lpWithdraw(
uint256 glUsdAmount,
uint256 minUsdcOut,
uint256 minBearOut
) internal returns (uint256 usdcReturned, uint256 bearReturned);
lpDeposit
Direct LP deposit: provide USDC and/or plDXY-BEAR, deploy to Curve, mint INVAR.
Inverse of lpWithdraw. Curve slippage is borne by the depositor, not existing holders. Shares are priced using pessimistic LP valuation so the depositor cannot extract value from a stale-high EMA. Spot deviation is checked against EMA to block sandwich attacks. Reverts while emergencyActive is true.
function lpDeposit(
uint256 usdcAmount,
uint256 bearAmount,
address receiver,
uint256 minSharesOut
) external nonReentrant whenNotPaused returns (uint256 glUsdMinted);
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | Amount of USDC to deposit (6 decimals, can be 0 if bearAmount > 0). |
bearAmount | uint256 | Amount of plDXY-BEAR to deposit (18 decimals, can be 0 if usdcAmount > 0). |
receiver | address | Address that receives the minted INVAR shares. |
minSharesOut | uint256 | Minimum INVAR shares to receive (slippage protection). |
Returns
| Name | Type | Description |
|---|---|---|
glUsdMinted | uint256 | Number of INVAR shares minted. |
harvest
Permissionless keeper harvest for Curve LP fee yield.
Measures fee yield as virtual price growth above the cost basis (curveLpCostVp). Mints INVAR proportional to the USDC value of yield and donates it to sINVAR stakers. Only tracks VP growth on vault-deployed LP (trackedLpBalance), not donated LP. Reverts if no yield is available — use as a heartbeat signal for keepers.
function harvest() external nonReentrant whenNotPaused returns (uint256 donated);
Returns
| Name | Type | Description |
|---|---|---|
donated | uint256 | Amount of INVAR minted and donated to sINVAR. |
_harvestSafe
Harvest yield before withdrawals. Best-effort: skips when no yield is pending, Curve is down, or oracle is unavailable. Withdrawals must never be blocked by oracle outages.
function _harvestSafe() internal;
_harvest
Uses trackedLpBalance (not _lpBalance()) so donated LP cannot inflate harvestable yield. Divergence from actual LP is prevented by internal gaugeStakedLp tracking and forceRemoveGauge() which writes off stuck LP from both trackedLpBalance and curveLpCostVp.
function _harvest() internal returns (uint256 donated);
_mintAndDonate
function _mintAndDonate(
uint256 amount
) private;
_harvestWithPrice
function _harvestWithPrice(
uint256 lpBal,
uint256 currentVpValue,
uint256 oraclePrice
) private returns (uint256 donated);
donateUsdc
Accepts USDC donations from RewardDistributor, mints proportional INVAR, and donates to sINVAR.
function donateUsdc(
uint256 usdcAmount
) external nonReentrant whenNotPaused;
Parameters
| Name | Type | Description |
|---|---|---|
usdcAmount | uint256 | Amount of USDC to donate (6 decimals). |
deployToCurve
Permissionless keeper function: deploys excess USDC buffer into Curve as single-sided liquidity.
Maintains a 2% USDC buffer (BUFFER_TARGET_BPS). Only deploys if excess exceeds DEPLOY_THRESHOLD ($1000). Spot-vs-EMA deviation check (MAX_SPOT_DEVIATION_BPS = 0.5%) blocks deployment during pool manipulation.
function deployToCurve(
uint256 maxUsdc
) external nonReentrant whenNotPaused returns (uint256 lpMinted);
Parameters
| Name | Type | Description |
|---|---|---|
maxUsdc | uint256 | Cap on USDC to deploy (0 = no cap, deploy entire excess). |
Returns
| Name | Type | Description |
|---|---|---|
lpMinted | uint256 | Amount of Curve LP tokens minted. |
replenishBuffer
Permissionless keeper function: restores USDC buffer by burning Curve LP (single-sided to USDC).
Inverse of deployToCurve. Uses same spot-vs-EMA deviation check for sandwich protection. The maxLpToBurn parameter allows chunked replenishment when the full withdrawal would exceed the 0.5% spot deviation limit due to price impact.
function replenishBuffer(
uint256 maxLpToBurn
) external nonReentrant whenNotPaused returns (uint256 usdcRecovered);
Parameters
| Name | Type | Description |
|---|---|---|
maxLpToBurn | uint256 | Cap on LP tokens to burn (0 = no cap, burn entire deficit). |
redeployToCurve
Re-deploys recovered BEAR + excess USDC to Curve after emergency recovery.
Clears emergencyActive flag. Should only be called after emergencyWithdrawFromCurve() has recovered the BEAR tokens from the pool.
function redeployToCurve(
uint256 minLpOut
) external onlyOwner nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
minLpOut | uint256 | Minimum LP tokens to mint (slippage protection for the two-sided deposit). |
setEmergencyMode
Activates emergency mode without touching Curve.
Pauses the contract and blocks deposits plus single-sided withdrawals. LP accounting is left intact so users retain their pro-rata claim once balanced exits recover.
function setEmergencyMode() external onlyOwner;
forceRemoveGauge
Write off a bricked gauge and its stuck LP from accounting.
Only callable during emergencyActive. Clears curveGauge, proportionally reduces trackedLpBalance and curveLpCostVp for the lost LP, and zeros gaugeStakedLp. After this, emergencyWithdrawFromCurve() or lpWithdraw() can proceed with remaining local LP.
function forceRemoveGauge() external onlyOwner;
emergencyWithdrawFromCurve
Attempts to recover LP tokens from Curve via balanced remove_liquidity.
Also callable as a standalone emergency — sets emergencyActive, pauses, and only zeroes tracked LP accounting after the LP has actually been recovered. If Curve is bricked, the remove_liquidity call reverts and the entire tx rolls back, leaving state unchanged. Use setEmergencyMode() first in that case.
function emergencyWithdrawFromCurve() external onlyOwner nonReentrant;
setGaugeApproval
function setGaugeApproval(
address gauge,
bool approved
) external onlyOwner;
pause
function pause() external onlyOwner;
unpause
function unpause() external onlyOwner;
rescueToken
Rescue accidentally sent ERC20 tokens. Cannot rescue USDC, BEAR, or Curve LP.
function rescueToken(
address token,
address to
) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
token | address | Address of the token to rescue. |
to | address | Destination address for the rescued tokens. |
proposeGauge
Propose a new Curve gauge for LP staking. Subject to GAUGE_TIMELOCK delay.
function proposeGauge(
address _gauge
) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
_gauge | address | Address of the new gauge (address(0) to remove gauge). |
finalizeGauge
Finalize a pending gauge change after the timelock expires.
This MUST revert if oldGauge.withdraw() fails. Do NOT wrap in try/catch: silent failure would update curveGauge to newGauge while LP stays locked in oldGauge, causing _lpBalance() to forget the stuck LP and collapsing totalAssets(). If the old gauge is permanently bricked, use setEmergencyMode() instead.
function finalizeGauge() external onlyOwner;
stakeToGauge
Stake LP tokens to the active Curve gauge.
function stakeToGauge(
uint256 amount
) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of LP to stake (0 = all unstaked LP). |
unstakeFromGauge
Unstake LP tokens from the active Curve gauge.
function unstakeFromGauge(
uint256 amount
) external onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
amount | uint256 | Amount of LP to unstake (0 = all staked LP). |
claimGaugeRewards
Claim CRV + extra rewards from the gauge. Use rescueToken() to sweep reward tokens.
On L1, CRV is minted via the Curve Minter (not claim_rewards). On L2, claim_rewards handles CRV.
function claimGaugeRewards() external onlyOwner;
Events
Deposited
event Deposited(address indexed user, address indexed receiver, uint256 usdcIn, uint256 glUsdOut);
Withdrawn
event Withdrawn(address indexed user, address indexed receiver, uint256 glUsdIn, uint256 usdcOut);
LpWithdrawn
event LpWithdrawn(address indexed user, uint256 sharesBurned, uint256 usdcReturned, uint256 bearReturned);
LpDeposited
event LpDeposited(address indexed user, address indexed receiver, uint256 usdcIn, uint256 bearIn, uint256 glUsdOut);
DeployedToCurve
event DeployedToCurve(address indexed caller, uint256 usdcDeployed, uint256 bearDeployed, uint256 lpMinted);
BufferReplenished
event BufferReplenished(uint256 lpBurned, uint256 usdcRecovered);
YieldHarvested
event YieldHarvested(uint256 glUsdMinted, uint256 callerReward, uint256 donated);
TokenRescued
event TokenRescued(address indexed token, address indexed to, uint256 amount);
EmergencyWithdrawCurve
event EmergencyWithdrawCurve(uint256 lpBurned, uint256 usdcReceived, uint256 bearReceived);
StakedInvarCoinProposed
event StakedInvarCoinProposed(address indexed stakedInvarCoin, uint256 activationTime);
StakedInvarCoinSet
event StakedInvarCoinSet(address indexed stakedInvarCoin);
GaugeProposed
event GaugeProposed(address indexed gauge, uint256 activationTime);
GaugeUpdated
event GaugeUpdated(address indexed oldGauge, address indexed newGauge);
GaugeRewardsReceiverProposed
event GaugeRewardsReceiverProposed(address indexed receiver, uint256 activationTime);
GaugeRewardsReceiverSet
event GaugeRewardsReceiverSet(address indexed receiver);
RewardTokenProtected
event RewardTokenProtected(address indexed token);
GaugeStaked
event GaugeStaked(uint256 amount);
GaugeUnstaked
event GaugeUnstaked(uint256 amount);
GaugeRewardsClaimed
event GaugeRewardsClaimed();
GaugeRewardsSwept
event GaugeRewardsSwept(address indexed token, address indexed receiver, uint256 amount);
UsdcDonated
event UsdcDonated(address indexed donor, uint256 usdcAmount, uint256 invarMinted);
GaugeForceRemoved
event GaugeForceRemoved(address indexed gauge, uint256 lpLost);
Errors
InvarCoin__ZeroAmount
error InvarCoin__ZeroAmount();
InvarCoin__StakingNotSet
error InvarCoin__StakingNotSet();
InvarCoin__ZeroAddress
error InvarCoin__ZeroAddress();
InvarCoin__SlippageExceeded
error InvarCoin__SlippageExceeded();
InvarCoin__NothingToDeploy
error InvarCoin__NothingToDeploy();
InvarCoin__NoYield
error InvarCoin__NoYield();
InvarCoin__CannotRescueCoreAsset
error InvarCoin__CannotRescueCoreAsset();
InvarCoin__PermitFailed
error InvarCoin__PermitFailed();
InvarCoin__AlreadySet
error InvarCoin__AlreadySet();
InvarCoin__SpotDeviationTooHigh
error InvarCoin__SpotDeviationTooHigh();
InvarCoin__UseLpWithdraw
error InvarCoin__UseLpWithdraw();
InvarCoin__Unauthorized
error InvarCoin__Unauthorized();
InvarCoin__GaugeTimelockActive
error InvarCoin__GaugeTimelockActive();
InvarCoin__StakingTimelockActive
error InvarCoin__StakingTimelockActive();
InvarCoin__GaugeRewardsTimelockActive
error InvarCoin__GaugeRewardsTimelockActive();
InvarCoin__InvalidProposal
error InvarCoin__InvalidProposal();
InvarCoin__NoGauge
error InvarCoin__NoGauge();
InvarCoin__EmergencyActive
error InvarCoin__EmergencyActive();
InvarCoin__InvalidGauge
error InvarCoin__InvalidGauge();
InvarCoin__InvalidStakingVault
error InvarCoin__InvalidStakingVault();
InvarCoin__GaugeRewardsReceiverNotSet
error InvarCoin__GaugeRewardsReceiverNotSet();
InvarCoin__NotEmergency
error InvarCoin__NotEmergency();