Skip to main content

BaseBalancerStrategy

BaseBalancerStrategy​

rETH​

address rETH

stETH​

address stETH

wstETH​

address wstETH

frxETH​

address frxETH

sfrxETH​

address sfrxETH

balancerVault​

contract IBalancerVault balancerVault

Address of the Balancer vault

balancerPoolId​

bytes32 balancerPoolId

Balancer pool identifier

maxWithdrawalDeviation​

uint256 maxWithdrawalDeviation

maxDepositDeviation​

uint256 maxDepositDeviation

BaseBalancerConfig​

struct BaseBalancerConfig {
address rEthAddress;
address stEthAddress;
address wstEthAddress;
address frxEthAddress;
address sfrxEthAddress;
address balancerVaultAddress;
bytes32 balancerPoolId;
}

MaxWithdrawalDeviationUpdated​

event MaxWithdrawalDeviationUpdated(uint256 _prevMaxDeviationPercentage, uint256 _newMaxDeviationPercentage)

MaxDepositDeviationUpdated​

event MaxDepositDeviationUpdated(uint256 _prevMaxDeviationPercentage, uint256 _newMaxDeviationPercentage)

whenNotInBalancerVaultContext​

modifier whenNotInBalancerVaultContext()

_Ensure we are not in a Vault context when this function is called, by attempting a no-op internal balance operation. If we are already in a Vault transaction (e.g., a swap, join, or exit), the Vault's reentrancy protection will cause this function to revert.

Use this modifier with any function that can cause a state change in a pool and is either public itself, or called by a public function outside a Vault operation (e.g., join, exit, or swap).

This is to protect against Balancer's read-only re-entrancy vulnerability: https://www.notion.so/originprotocol/Balancer-read-only-reentrancy-c686e72c82414ef18fa34312bb02e11b_

constructor​

constructor(struct BaseBalancerStrategy.BaseBalancerConfig _balancerConfig) internal

initialize​

function initialize(address[] _rewardTokenAddresses, address[] _assets, address[] _pTokens) external

Initializer for setting up strategy internal state. This overrides the InitializableAbstractStrategy initializer as Balancer's strategies don't fit well within that abstraction.

Parameters​

NameTypeDescription
_rewardTokenAddressesaddress[]Address of BAL & AURA
_assetsaddress[]Addresses of supported assets. MUST be passed in the same order as returned by coins on the pool contract, i.e. WETH, stETH
_pTokensaddress[]Platform Token corresponding addresses

supportsAsset​

function supportsAsset(address _asset) public view returns (bool)

Returns bool indicating whether asset is supported by strategy

Parameters​

NameTypeDescription
_assetaddressAddress of the asset

checkBalance​

function checkBalance(address _asset) external view virtual returns (uint256 amount)

Get strategy's share of an assets in the Balancer pool. This is not denominated in OUSD/ETH value of the assets in the Balancer pool.

it is important that this function is not affected by reporting inflated values of assets in case of any pool manipulation. Such a manipulation could easily exploit the protocol by:

  • minting OETH
  • tilting Balancer pool to report higher balances of assets
  • rebasing() -> all that extra token balances get distributed to OETH holders
  • tilting pool back
  • redeeming OETH

Parameters​

NameTypeDescription
_assetaddressAddress of the Vault collateral asset

Return Values​

NameTypeDescription
amountuint256the amount of vault collateral assets IMPORTANT if this function is overridden it needs to have a whenNotInBalancerVaultContext modifier on it or it is susceptible to read-only re-entrancy attack

checkBalance​

function checkBalance() external view virtual returns (uint256 value)

Returns the value of all assets managed by this strategy. Uses the Balancer pool's rate (virtual price) to convert the strategy's Balancer Pool Tokens (BPT) to ETH value.

Return Values​

NameTypeDescription
valueuint256The ETH value IMPORTANT if this function is overridden it needs to have a whenNotInBalancerVaultContext modifier on it or it is susceptible to read-only re-entrancy attack

_getBalancerPoolTokens​

function _getBalancerPoolTokens() internal view virtual returns (uint256 balancerPoolTokens)

Balancer Pool Tokens (BPT) in the Balancer pool.

_getBPTExpected​

function _getBPTExpected(address _asset, uint256 _amount) internal view virtual returns (uint256 bptExpected)

BPT price is calculated by taking the rate from the rateProvider of the asset in question. If one does not exist it defaults to 1e18. To get the final BPT expected that is multiplied by the underlying asset amount divided by BPT token rate. BPT token rate is similar to Curve's virtual_price and expresses how much has the price of BPT appreciated (e.g. due to swap fees) in relation to the underlying assets

Using the above approach makes the strategy vulnerable to a possible MEV attack using flash loan to manipulate the pool before a deposit/withdrawal since the function ignores market values of the assets being priced in BPT.

At the time of writing there is no safe on-chain approach to pricing BPT in a way that it would make it invulnerable to MEV pool manipulation. See recent Balancer exploit: https://www.notion.so/originprotocol/Balancer-OETH-strategy-9becdea132704e588782a919d7d471eb?pvs=4#1cf07de12fc64f1888072321e0644348

To mitigate MEV possibilities during deposits and withdraws, the VaultValueChecker will use checkBalance before and after the move to ensure the expected changes took place.

Parameters​

NameTypeDescription
_assetaddressAddress of the Balancer pool asset
_amountuint256Amount of the Balancer pool asset

Return Values​

NameTypeDescription
bptExpecteduint256of BPT expected in exchange for the asset @dev bptAssetPrice = 1e18 (asset peg) * pool_asset_rate bptExpected = bptAssetPrice * asset_amount / BPT_token_rate bptExpected = 1e18 (asset peg) * pool_asset_rate * asset_amount / BPT_token_rate bptExpected = asset_amount * pool_asset_rate / BPT_token_rate further information available here: https://www.notion.so/originprotocol/Balancer-OETH-strategy-9becdea132704e588782a919d7d471eb?pvs=4#ce01495ae70346d8971f5dced809fb83

_getBPTExpected​

function _getBPTExpected(address[] _assets, uint256[] _amounts) internal view virtual returns (uint256 bptExpected)

_lpDepositAll​

function _lpDepositAll() internal virtual

_lpWithdraw​

function _lpWithdraw(uint256 numBPTTokens) internal virtual

_lpWithdrawAll​

function _lpWithdrawAll() internal virtual

_getPoolAssets​

function _getPoolAssets() internal view returns (contract IERC20[] assets)

Balancer returns assets and rateProviders for corresponding assets ordered by numerical order.

_toPoolAsset​

function _toPoolAsset(address asset, uint256 amount) internal view returns (address poolAsset, uint256 poolAmount)

If an asset is rebasing the Balancer pools have a wrapped versions of assets that the strategy supports. This function converts the pool(wrapped) asset and corresponding amount to strategy asset.

_toPoolAsset​

function _toPoolAsset(address asset) internal view returns (address)

Converts a Vault collateral asset to a Balancer pool asset. stETH becomes wstETH, frxETH becomes sfrxETH and everything else stays the same.

Parameters​

NameTypeDescription
assetaddressAddress of the Vault collateral asset.

Return Values​

NameTypeDescription
[0]addressAddress of the Balancer pool asset.

_wrapPoolAsset​

function _wrapPoolAsset(address asset, uint256 amount) internal returns (address wrappedAsset, uint256 wrappedAmount)

Converts rebasing asset to its wrapped counterpart.

_unwrapPoolAsset​

function _unwrapPoolAsset(address asset, uint256 amount) internal returns (uint256 unwrappedAmount)

Converts wrapped asset to its rebasing counterpart.

_fromPoolAsset​

function _fromPoolAsset(address poolAsset, uint256 poolAmount) internal view returns (address asset, uint256 amount)

If an asset is rebasing the Balancer pools have a wrapped versions of assets that the strategy supports. This function converts the rebasing strategy asset and corresponding amount to wrapped(pool) asset.

_fromPoolAsset​

function _fromPoolAsset(address poolAsset) internal view returns (address asset)

setMaxWithdrawalDeviation​

function setMaxWithdrawalDeviation(uint256 _maxWithdrawalDeviation) external

Sets max withdrawal deviation that is considered when removing liquidity from Balancer pools.

Parameters​

NameTypeDescription
_maxWithdrawalDeviationuint256Max withdrawal deviation denominated in wad (number with 18 decimals): 1e18 == 100%, 1e16 == 1% IMPORTANT Minimum maxWithdrawalDeviation will be 1% (1e16) for production usage. Vault value checker in combination with checkBalance will catch any unexpected manipulation.

setMaxDepositDeviation​

function setMaxDepositDeviation(uint256 _maxDepositDeviation) external

Sets max deposit deviation that is considered when adding liquidity to Balancer pools.

Parameters​

NameTypeDescription
_maxDepositDeviationuint256Max deposit deviation denominated in wad (number with 18 decimals): 1e18 == 100%, 1e16 == 1% IMPORTANT Minimum maxDepositDeviation will default to 1% (1e16) for production usage. Vault value checker in combination with checkBalance will catch any unexpected manipulation.

_approveBase​

function _approveBase() internal virtual

_getRateProviderRate​

function _getRateProviderRate(address _asset) internal view virtual returns (uint256)