Sugar comes with contracts to help working with Velodrome Finance data!
The idea is pretty simple, instead of relying on our API for a structured data set of liquidity pool data, these contracts can be called in an efficient way to directly fetch the same data off-chain.
What normally would require:
- fetching the number of liquidity pools
- querying every pool address at it's index
- querying pool tokens data
- querying gauge addresses and reward rate
Takes a single call with sugar!
More importantly, the response can be paginated.
Main goals of this little project are:
- to maximize the developers UX of working with our protocol
- simplify complexity
- document and test everything
On-chain data is organized for transaction cost and efficiency. We think
we can hide a lot of the complexity by leveraging structs
to present the data
and normalize it based on it's relevancy.
Below is the list of datasets we support.
Note
LpSugar.vy
is deployed at 0xa8D674c71d34798Ec65C6cb1d2e7c0864735d2FD
It allows fetching on-chain pools data.
The returned data/struct of type Lp
values represent:
lp
- pool contract addresssymbol
- pool symboldecimals
- pool decimalsliquidity
- pool tokens supplytype
- tick spacing on CL pools, 0/-1 for stable/volatile on v2 poolstick
- current tick on CL pools, 0 on v2 poolssqrt_ratio
- pool sqrt ratio X96 on CL pools, 0 on v2 poolstoken0
- pool 1st token addressreserve0
- pool 1st token reserves (nr. of tokens in the contract)staked0
- pool 1st token staked amounttoken1
- pool 2nd token addressreserve1
- pool 2nd token reserves (nr. of tokens in the contract)staked1
- pool 2nd token staked amountgauge
- pool gauge addressgauge_liquidity
- pool staked tokens (less/eq than/to pool total supply)gauge_alive
- indicates if the gauge is still activefee
- pool gauge fees contract address, CL pools use hundredths of a bip (i.e. 1e-6)bribe
- pool gauge bribes contract addressfactory
- pool factory addressemissions
- pool emissions (per second)emissions_token
- pool emissions token addresspool_fee
- pool swap fee (percentage)unstaked_fee
- unstaked fee percentage on CL pools, 0 on v2 poolstoken0_fees
- current epoch token0 accrued fees (next week gauge fees)token1_fees
- current epoch token1 accrued fees (next week gauge fees)
The available methods are:
all(_limit: uint256, _offset: uint256) -> Lp[]
- returns a paginated list ofLp
structs.byIndex(_index: uint256) -> Lp
- returns theLp
data for a specific index of a pool.
To get the positions of an account, use this function:
positions(_account: address) -> Position[]
The returned data is a struct of type Position
with the following values:
id
- NFT ID on CL pools, 0 on v2 poolsliquidity
- liquidity amount on CL, deposited LP tokens on v2staked
- staked/unstaked liquidity amount on CL, amount of staked tokens on v2amount0
- amount of unstaked token0 in the positionamount1
- amount of unstaked token1 in the positionstaked1
- amount of staked token0 in the positionstaked1
- amount of staked token1 in the positionunstaked_earned0
- unstaked token0 fees earnedunstaked_earned1
- unstaked token1 fees earnedemissions_earned
- emissions earned from staked positiontick_lower
- lower tick of position on CL, 0 on v2tick_upper
- upper tick of position on CL, 0 on v2sqrt_ratio_lower
- sqrt ratio X96 at lower tick on CL, 0 on v2sqrt_ratio_upper
- sqrt ratio X96 at upper tick on CL, 0 on v2
For the pool epoch data we return, starting with most recent epoch, a struct of
type LpEpoch
with the following values:
ts
- the start of the epoch/week timestamplp
- the pool addressvotes
- the amount of the votes for that epoch/weekemissions
- emissions per second for that epoch/weekbribes
- a list of bribes data, it is a struct of typeLpEpochBribe
with the following values:token
- bribe token addressamount
- bribe amount
fees
- a list of fees data, it is a struct of typeLpEpochBribe
, just like thebribes
list
To fetch a list of epochs for a specific pool, this method is available:
epochsByAddress(_limit: uint256, _offset: uint256, _address: address) -> LpEpoch[]
To fetch a list of latest epochs data for a every pool, this method is available:
epochsLatest(_limit: uint256, _offset: uint256) -> LpEpoch[]
The pools token list (compiled from all the pools token0
/token1
) uses the type
Token
with the following values:
token_address
- the token addresssymbol
- the token symboldecimals
- the token decimalsaccount_balance
- the provided account/wallet balancelisted
- indicates if the token was listed for gauge voting rewards
To fetch the token list this method is available:
tokens(_limit: uint256, _offset: uint256, _account: address, _oracle: address, _oracle_connectors: address[]) -> Token[]
For the rewards, we return a struct of type Reward
with the following
values:
venft_id
- the veNFT id it belongs tolp
- the pool address representing the source of the rewardamount
- the amount of the tokens accruedtoken
- the reward token addressfee
- the fee contract address (if the reward comes from fees)bribe
- the bribe contract address (if the reward comes from bribes)
To fetch a list of rewards for a specific veNFT, this method is available:
rewards(_limit: uint256, _offset: uint256, _venft_id: uint256) -> Reward[]
rewardsByAddress(_venft_id: uint256, _pool: address) -> Reward[]
Note
VeSugar.vy
is deployed at 0x37403dBd6f1b583ea244F7956fF9e37EF45c63eB
It allows fetching on-chain veNFT data (including the rewards accrued).
The returned data/struct of type VeNFT
values represent:
id
- veNFT token IDaccount
- veNFT token account addressdecimals
- veNFT token decimalsamount
- veNFT locked amountvoting_amount
- veNFT voting powergovernance_amount
- veNFT voting power in governancerebase_amount
- veNFT accrued reabses amountexpires_at
- veNFT lock expiration timestampvoted_at
- veNFT last vote timestampvotes
- veNFT list of pools with vote weights casted in the form ofLpVotes
token
- veNFT locked token addresspermanent
- veNFT permanent lock enabled flagdelegate_id
- token ID of the veNFT being delegated to
The pool votes struct values represent:
lp
- the pool addressweight
- the vote weights of the vote for the pool
The available methods are:
all(_limit: uint256, _offset: uint256) -> VeNFT[]
- returns a paginated list ofveNFT
structs.byAccount(_account: address) -> VeNFT[]
- returns a list ofVeNFT
structs for a specific account.byId(_id: uint256) -> VeNFT
- returns theVeNFT
struct for a specific NFT id.
Note
RelaySugar.vy
is deployed at 0xb8307e5842B9aeE75C704183F0355076aa74b4e2
It allows fetching Relay autocompounder/autoconverter data.
The returned data/struct of type Relay
values represent:
venft_id
- token ID of the Relay veNFTdecimals
- Relay veNFT token decimalsamount
- Relay veNFT locked amountvoting_amount
- Relay veNFT voting powerused_voting_amount
- Relay veNFT voting power used for last votevoted_at
- Relay veNFT last vote timestampvotes
- Relay veNFT list of pools with vote weights casted in the form ofLpVotes
token
- token address the Relay is compounding intocompounded
- amount of tokens compounded into in the recent epochrun_at
- timestamp of last compoundingmanager
- Relay managerrelay
- Relay addressinactive
- Relay active/inactive statusname
- Relay nameaccount_venfts
- List of veNFTs deposited into this Relay by the account in the form ofManagedVenft
The managed veNFT deposit struct values represent:
id
- the token ID of the veNFTamount
- the weight of the veNFTearned
- earned emissions of the veNFT
The available methods are:
all(_account: address) -> Relay[]
- returns a list of allRelay
structs.
To setup the environment, build the Docker image first:
docker build ./ -t velodrome/sugar
Next start the container with existing environment variables:
docker run --env-file=env.example --rm -v $(pwd):/app -w /app -it velodrome/sugar sh
The environment has Brownie and Vyper already installed.
To run the tests inside the container, use:
brownie test --network=optimism-test
Sugar is written in Vyper, and Optimistic Etherscan fails at times to
generate the same bytecode (probably because of the hardcoded evm_version
).
Consider using the web tool at https://abi.hashex.org to build the arguments and provide the generated value as part of the Etherscan verification form.