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 pairs 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 pairs
- querying every pair address at it's index
- querying pair 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.
PairsSugar.vy
is deployed at 0x8b70c5e53235abbd1415957f7110fbfe5d0529d4
It allows fetching on-chain pairs data.
The returned data/struct of type Pair
values represent:
pair_address
- pair contract addresssymbol
- pair symboldecimals
- pair decimalsstable
- pair pool type (stable = false
, means it's a variable type of pool)total_supply
- pair tokens supplytoken0
- pair 1st token addressreserve0
- pair 1st token reserves (nr. of tokens in the contract)claimable0
- claimable 1st token from fees (for unstaked positions)token1
- pair 2nd token addressreserve1
- pair 2nd token reserves (nr. of tokens in the contract)claimable1
- claimable 2nd token from fees (for unstaked positions)gauge
- pair gauge addressgauge_total_supply
- pair staked tokens (less/eq than/to pair total supply)gauge_alive
- indicates if the gauge is still activefee
- pair fees contract addressbribe
- pair bribes contract addresswrapped_bribe
- pair wrapped bribe contract addressemissions
- pair emissions (per second)emissions_token
- pair emissions token addressaccount_balance
- account LP tokens balanceaccount_earned
- account earned emissions for this pairaccount_staked
- account pair staked in gauge balance
The available methods are:
all(_limit: uint256, _offset: uint256, _account: address) -> Pair[]
- returns a paginated list ofPair
structs.byIndex(_index: uint256, _account: address) -> Pair
- returns thePair
data for a specific index of a pair.byAddress(_address: address, _account: address) -> Pair
- returns thePair
data for a specific pair address.
For the pair epoch data we return, starting with most recent epoch, a struct of
type PairEpoch
with the following values:
ts
- the start of the epoch/week timestamppair_address
- the pair 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 typePairEpochBribe
with the following values:token
- bribe token addressamount
- bribe amount
fees
- a list of fees data, it is a struct of typePairEpochBribe
, just like thebribes
list
To fetch a list of epochs for a specific pair, this method is available:
epochsByAddress(_limit: uint256, _offset: uint256, _address: address) -> PairEpoch[]
To fetch a list of latest epochs data for a every pair, this method is available:
epochsLatest(_limit: uint256, _offset: uint256) -> PairEpoch[]
The pairs 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[]
VeSugar.vy
is deployed at 0x925A0d9d2000c4919e7BF0a0d5F2995a2bfE8542
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 powerrebase_amount
- veNFT accrued reabses amountexpires_at
- veNFT lock expiration timestampvoted_at
- veNFT last vote timestampvotes
- veNFT list of pairs with vote weights casted in the form ofPairVotes
token
- veNFT locked token addressattachments
- veNFT nr. of attachments (aka gauges it is attached to)
The pair votes struct values represent:
pair
- the pair addressweight
- the vote weights of the vote for the pair
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.
For the veNFT rewards, we return a struct of type Reward
with the following
values:
venft_id
- the veNFT id it belongs topair
- the pair 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[]
rewardsByPair(_venft_id: uint256, _pair: address) -> Reward[]
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
).