# Loopfi for Velodrome ###### tags: `Deployed Contracts` [TOC] ## References - https://docs.solidexfinance.com/developers/architecture - https://github.com/DoubleClub/double ## Contract Addresses ### Optimism 10-09 | | address | link | |:-------------------|:-------------------------------------------|:-------------------------------------------------------------------------------------------| | LPF | 0x0B3e851cf6508A16266BC68A651ea68b31ef673b | [link](https://optimistic.etherscan.io/address/0x0B3e851cf6508A16266BC68A651ea68b31ef673b) | | velo | 0x3c8B650257cFb5f272f799F5e2b4e65093a11a05 | [link](https://optimistic.etherscan.io/address/0x3c8B650257cFb5f272f799F5e2b4e65093a11a05) | | veVELO | 0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26 | [link](https://optimistic.etherscan.io/address/0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26) | | USXDFLP | 0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa | [link](https://optimistic.etherscan.io/address/0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa) | | proxyAdmin | 0xCaba6cfd4C83E1806467d937842D18128f90C13b | [link](https://optimistic.etherscan.io/address/0xCaba6cfd4C83E1806467d937842D18128f90C13b) | | VeDepositorImpl | 0x93FC1235119c554576D8AB23583371fc25B803ee | [link](https://optimistic.etherscan.io/address/0x93FC1235119c554576D8AB23583371fc25B803ee) | | veDepositor (pVELO) | 0x045999103f084AC539aCd1c6De157cAa54d4Ca02 | [link](https://optimistic.etherscan.io/address/0x045999103f084AC539aCd1c6De157cAa54d4Ca02) | | LpDepositorImpl | 0x6fA4D572aaaCa121f90e32c7460c736cc033A281 | [link](https://optimistic.etherscan.io/address/0x6fA4D572aaaCa121f90e32c7460c736cc033A281) | | lpDepositor | 0x96E113F64f5188eeB4990f11254C443404E68E08 | [link](https://optimistic.etherscan.io/address/0x96E113F64f5188eeB4990f11254C443404E68E08) | | lpDepositToken | 0x68B0BB1711e0d86258Fc6982dE197c827749D91F | [link](https://optimistic.etherscan.io/address/0x68B0BB1711e0d86258Fc6982dE197c827749D91F) | | StakingRewardsImpl | 0x3650B69f86cB593f116e276C30666834336c0647 | [link](https://optimistic.etherscan.io/address/0x3650B69f86cB593f116e276C30666834336c0647) | | pVeloStaking | 0x11a2032Fa2f2Cb636bDe9C9d33E3807FD372bE06 | [link](https://optimistic.etherscan.io/address/0x11a2032Fa2f2Cb636bDe9C9d33E3807FD372bE06) | | treasuryFunds | 0xE80eb6E7CC0e076D01331EceF0e96ae66ec4b533 | [link](https://optimistic.etherscan.io/address/0xE80eb6E7CC0e076D01331EceF0e96ae66ec4b533) | ### Locker Update 09-22 - https://rpc.dforce.network/9008/ | | address | link | |:-------------------|:-------------------------------------------|:-------------------------------------------------------------------------------------------| | LPF | 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1 | [link](https://optimistic.etherscan.io/address/0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1) | | velo | 0x3c8B650257cFb5f272f799F5e2b4e65093a11a05 | [link](https://optimistic.etherscan.io/address/0x3c8B650257cFb5f272f799F5e2b4e65093a11a05) | | veVELO | 0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26 | [link](https://optimistic.etherscan.io/address/0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26) | | USXDFLP | 0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa | [link](https://optimistic.etherscan.io/address/0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa) | | VELOOPLP | 0xFFD74EF185989BFF8752c818A53a47FC45388F08 | [link](https://optimistic.etherscan.io/address/0xFFD74EF185989BFF8752c818A53a47FC45388F08) | | proxyAdmin | 0xb1B029C627500FfF63B2E569AA69620256eA0d14 | [link](https://optimistic.etherscan.io/address/0xb1B029C627500FfF63B2E569AA69620256eA0d14) | | VeDepositorImpl | 0xAffB10e966Cbd7273Ac4BD95Bdb00e160ADf96cF | [link](https://optimistic.etherscan.io/address/0xAffB10e966Cbd7273Ac4BD95Bdb00e160ADf96cF) | | veDepositor | 0xF125f848e80df8640Fe5a251d872B6a16418A622 | [link](https://optimistic.etherscan.io/address/0xF125f848e80df8640Fe5a251d872B6a16418A622) | | LpDepositorImpl | 0x4EcDF0841b1972c242E3Ba93cF71a6Df9a71f44f | [link](https://optimistic.etherscan.io/address/0x4EcDF0841b1972c242E3Ba93cF71a6Df9a71f44f) | | lpDepositor | 0x213B7b694B29eC4CdC62fb21b0c7C76e8e7b0b71 | [link](https://optimistic.etherscan.io/address/0x213B7b694B29eC4CdC62fb21b0c7C76e8e7b0b71) | | lpDepositToken | 0xa8c20EA02d54D135c992aC43FdEdc713a4d21563 | [link](https://optimistic.etherscan.io/address/0xa8c20EA02d54D135c992aC43FdEdc713a4d21563) | | StakingRewardsImpl | 0x628624E0b39301E718B60f733C5E01D5Ab3824C4 | [link](https://optimistic.etherscan.io/address/0x628624E0b39301E718B60f733C5E01D5Ab3824C4) | | pVeloStaking | 0x5FcaF78B929523e360c9d8EA1c1b434751189282 | [link](https://optimistic.etherscan.io/address/0x5FcaF78B929523e360c9d8EA1c1b434751189282) | | TokenLockerImpl | 0x08F2DBA180EA2929Ebb3a8E5cDdbD8482BF11130 | [link](https://optimistic.etherscan.io/address/0x08F2DBA180EA2929Ebb3a8E5cDdbD8482BF11130) | | lpfLocker | 0xD48F880BA9a4D591E99A6990EA272dC34fecfB52 | [link](https://optimistic.etherscan.io/address/0xD48F880BA9a4D591E99A6990EA272dC34fecfB52) | | FeeDistributorImpl | 0x0CD83eC4E36A025a5D1b82322ecD9FF934EE3a82 | [link](https://optimistic.etherscan.io/address/0x0CD83eC4E36A025a5D1b82322ecD9FF934EE3a82) | | feeDistributor | 0x52B54e191F0dC7b9b58D911fDdA184F741260604 | [link](https://optimistic.etherscan.io/address/0x52B54e191F0dC7b9b58D911fDdA184F741260604) | | DoubleVoterImpl | 0x58ec158195Ef5597176784f12BEC4EE22F89c718 | [link](https://optimistic.etherscan.io/address/0x58ec158195Ef5597176784f12BEC4EE22F89c718) | | doubleVoter | 0xAb8DA5f369d7e15aC8b24D9126DD6d1f7a6CD9Ef | [link](https://optimistic.etherscan.io/address/0xAb8DA5f369d7e15aC8b24D9126DD6d1f7a6CD9Ef) | ### Initial Deployments - https://rpc.dforce.network/9007/ | | address | link | |:-------------------|:-------------------------------------------|:-------------------------------------------------------------------------------------------| | LPF | 0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1 | [link](https://optimistic.etherscan.io/address/0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1) | | velo | 0x3c8B650257cFb5f272f799F5e2b4e65093a11a05 | [link](https://optimistic.etherscan.io/address/0x3c8B650257cFb5f272f799F5e2b4e65093a11a05) | | veVELO | 0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26 | [link](https://optimistic.etherscan.io/address/0x9c7305eb78a432ced5C4D14Cac27E8Ed569A2e26) | | DF/USX LP | 0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa | [link](https://optimistic.etherscan.io/address/0xf8eDF2Da8FcF610Cf77235D3F90CC110723159Aa) | | proxyAdmin | 0xE189e9585b392624c343b750632C00b452022d53 | [link](https://optimistic.etherscan.io/address/0xE189e9585b392624c343b750632C00b452022d53) | | VeDepositorImpl | 0xD86E43f400e65d1e68fE1eea409799506C51652F | [link](https://optimistic.etherscan.io/address/0xD86E43f400e65d1e68fE1eea409799506C51652F) | | veDepositor(pVelo) | 0x23b43BFE32cd10b2E3baAf8d5F0D763728922DA0 | [link](https://optimistic.etherscan.io/address/0x23b43BFE32cd10b2E3baAf8d5F0D763728922DA0) | | LpDepositorImpl | 0xA671198aC02b668b33F70A13131aC3175f60D100 | [link](https://optimistic.etherscan.io/address/0xA671198aC02b668b33F70A13131aC3175f60D100) | | lpDepositor | 0x6F4b714e5a9B32391E0c1EF177BccCce1B210eD6 | [link](https://optimistic.etherscan.io/address/0x6F4b714e5a9B32391E0c1EF177BccCce1B210eD6) | | lpDepositToken | 0xD1A914121F1A748E2f38f8572d815C95c2521E0B | [link](https://optimistic.etherscan.io/address/0xD1A914121F1A748E2f38f8572d815C95c2521E0B) | | StakingRewardsImpl | 0x6356Db2b8C550B41195efE605b02dbD2d42F0393 | [link](https://optimistic.etherscan.io/address/0x6356Db2b8C550B41195efE605b02dbD2d42F0393) | | pVeloStaking | 0xd3EefE9AEcC4F538434BAD29d82baBe7DA6C2C86 | [link](https://optimistic.etherscan.io/address/0xd3EefE9AEcC4F538434BAD29d82baBe7DA6C2C86) | | TokenLockerImpl | 0xF5A838fa72c77Dd3E8D4fEfe6862697CF1D5fC14 | [link](https://optimistic.etherscan.io/address/0xF5A838fa72c77Dd3E8D4fEfe6862697CF1D5fC14) | | lpfLocker | 0xA10df4d65E2DCEad594219E7d2996C4f8bdAa979 | [link](https://optimistic.etherscan.io/address/0xA10df4d65E2DCEad594219E7d2996C4f8bdAa979) | | FeeDistributorImpl | 0x29aF456D5084603766D9dc127740D92f719eF260 | [link](https://optimistic.etherscan.io/address/0x29aF456D5084603766D9dc127740D92f719eF260) | | feeDistributor | 0x2bd0ee211fef397e8BBeAd88B5C895e5092F478e | [link](https://optimistic.etherscan.io/address/0x2bd0ee211fef397e8BBeAd88B5C895e5092F478e) | | DoubleVoterImpl | 0xCe6DF50C87518D1C9F245C99B33317e4A962DfE0 | [link](https://optimistic.etherscan.io/address/0xCe6DF50C87518D1C9F245C99B33317e4A962DfE0) | | doubleVoter | 0x605F8Da6ca7B7Bb918A04Ed51A281c601BfC4932 | [link](https://optimistic.etherscan.io/address/0x605F8Da6ca7B7Bb918A04Ed51A281c601BfC4932) | ## ABI All abi can be found in https://github.com/dforce-network/Stranger/tree/dev/abi | Contract | ABI | |:-------------- |:---------------------------------------------------------------------------------------------------------- | | veDepositor | [VeDepositor.json](https://github.com/dforce-network/Stranger/tree/dev/abi/VeDepositor.json) | | lpDepositor | [LpDepositor.json](https://github.com/dforce-network/Stranger/tree/dev/abi/LpDepositor.json) | | pVeloStaking | [StakingRewards.json](https://github.com/dforce-network/Stranger/tree/dev/abi/StakingRewards.json) | | VELO | ERC20.json | | LPF | ERC20.json | ## Integration ### pVELO Staking #### Deposit Velo to get pVelo ##### ERC20 ```javascript await veDepositor.depositTokens(amount); ``` ##### veNFT ```javascript await veloVotingEscrow.safeTransferFrom(from, veDepositor.address, tokenID); ``` #### pVelo Staking ```javascript await pVeloStaking.stake(amount); await pVeloStaking.withdraw(amount); await pVeloStaking.getReward(); await pVeloStaking.exit(); const earned = await pVeloStaking.earned(account, velo.address); const earned = await pVeloStaking.earned(account, lpf.address); ``` #### pVelo Staking ```javascript await pVeloStaking.stake(amount); await pVeloStaking.withdraw(amount); await pVeloStaking.getReward(); await pVeloStaking.exit(); ``` #### pVelo Staking Reward ```javascript const earnedVELO = await pVeloStaking.earned(account, velo.address); const earnedLPF = await pVeloStaking.earned(account, lpf.address); ``` #### pVelo Staking Reward Rate for APY ```javascript const rewardRateVELO = (await pVeloStaking.rewardData(VELO))[1]; const rewardRateLPF = (await pVeloStaking.rewardData(LPF))[1]; ``` ### LP Gauge Staking #### Deposit LP ```javascript await lpDepositor.deposit(lp, amount); await lpDepositor.withdraw(lp, amount); await lpDepositor.getReward([lp1, lp2]); ``` #### Deposited Amount ```javascript const staked = await lpDepositor.userBalances(account, lp); ``` #### LP Reward [extraReward ABI](https://github.com/dforce-network/Stranger/blob/dev/abi/IBaseRewardPool.json) ```javascript // VELO const [earnedVelo] = await lpDepositor.pendingRewards(account, [lp1, lp2]); // LPF for some lp like pVELO/VELO const extraReward = await lpDepositor.extraRewardForPool(lp); const earnedLPF = await extraReward.earned(account); ``` #### LP Gauge reward rate [Gauge ABI](https://optimistic.etherscan.io/address/0x1F36f95a02C744f2B3cD196b5e44E749c153D3B9#code) [extraReward ABI](https://github.com/dforce-network/Stranger/blob/dev/abi/IBaseRewardPool.json) - rewardRate for VELO ```javascript // Get gauge const gaugeByPoolAddress = await lpDepositor.gaugeForPool(pool); // Initialize contract const gaugeContract = new ethers.Contract(gaugeByPoolAddress, IGauge.abi, provider); // Get rewards length const rewardsLength = await gaugeContract.rewardsListLength(); if (rewardsLength > 0) { // Get reward token const rewardAddress = await gaugeContract.rewards(0); const rewardRate = await gaugeContract.rewardRate(rewardAddress); } else { // There is something wrong! } ``` - rewardRate for LPF ```javascript const extraReward = await lpDepositor.extraRewardForPool(lp); const extraRewardContract = new ethers.Contract(extraReward, extraReward.abi, provider); const rewardToken = await extraRewardContract.rewardToken(); const rewardRateLPF = await extraRewardContract.rewardRate(); ``` #### Staked LP amount [Gauge ABI](https://optimistic.etherscan.io/address/0x1F36f95a02C744f2B3cD196b5e44E749c153D3B9#code) ```javascript! const gauge = await lpDepositor.gaugeForPool(lp); const totalLpStaked = await gauge.balanceOf(lpDepositor); ``` or ```javascript const totalLpStaked = await lpDepositor.totalBalances(lp); ``` #### Trigger Reward for pVeloStaking and treasury - Distribute Velo to pVELO stakers ```javascript const gaugeRewards = []; // VELO can not be claim here const bribeRewards = [VELO]; await lpDepositor.claimLockerRewards(lp, gaugeRewards, bribeRewards); // The 15% velo reward will be distributed // 10% goes to pVelo staker, 5% goes to treasury const amountToDistribute = await lpDepositor.unclaimedSolidBonus(); ``` - Distribute rebase Velo to treasury ```javascript await veDepositor.claimFromVeDistributor(); ``` ### LPF Locker #### Lock LPF ```javascript! await lpfLocker.lock(account, amount); ``` #### Unlock by ``` const getUnlockTime = async () => { const locker = new Lending.web3.eth.Contract(lockerABI, addressMap.locker) const rewardsDuration = await locker.methods.WEEK().call() const lockDuration = (await locker.methods.MAX_LOCK_WEEKS().call()) * rewardsDuration const currentTimestamp = Math.floor(new Date().getTime() / 1000) // console.log(rewardsDuration, lockDuration, currentTimestamp) const lockEpoch = Math.floor(currentTimestamp / rewardsDuration) * (rewardsDuration) const unlockTime = lockEpoch + Number(lockDuration) + Number(rewardsDuration) const time = new Date(unlockTime * 1000).getTime() // console.log(time) .toLocaleString() setUnlockTime(time) } ``` #### User Weight ```javascript! // Current weight const weight = await lpfLocker.userWeight(account); // Weight of week const time = Date.now() / 1000; const WEEK = 3600 * 24 * 7; const startTime = await lpfLocker.startTime(); const week = (time - startTime) / WEEK const weightOfWeek = await lpfLocker.weeklyWeight(account, week); ``` #### User Lock Balance (Vote weight in snapshot strategy) ```javascript! const balance = await lpfLocker.userBalance(account); ``` #### Get Lock info ```javascript! const activeLocks = await lpfLocker.getActiveUserLocks(account); for (lock of activeLocks) { const [remainingWeek, amount] = lock; } ``` #### Initiate Exit Stream ```javascript! // Get the streamable balance of user const steamable = await lpfLocker.streamableBalance(account); // Initiate the stream await lpfLocker.initiateExitStream(); ``` #### Withdraw Exit Stream ```javascript! // Get the claimable balance of user const claimable = await lpfLocker.claimableExitStreamBalance(account); // Withdraw await lpfLocker.withdrawExitStream(); ``` ## Notes ### LP Boost #### Velodrome remove the boost of ve https://docs.velodrome.finance/protocol#improvement-prolonged-emissions-decay #### Solidly https://ftmscan.com/address/0x03A1fbE02642F61A940093cc76fE5c4A2cbB8c24#code ``` function derivedBalance(address account) public view returns (uint) { uint _tokenId = tokenIds[account]; uint _balance = balanceOf[account]; uint _derived = _balance * 40 / 100; uint _adjusted = 0; uint _supply = erc20(_ve).totalSupply(); if (account == ve(_ve).ownerOf(_tokenId) && _supply > 0) { _adjusted = ve(_ve).balanceOfNFT(_tokenId); _adjusted = (totalSupply * _adjusted / _supply) * 60 / 100; } return Math.min((_derived + _adjusted), _balance); } ``` #### Velodrome https://optimistic.etherscan.io/address/0x59Bc700Acd8826675C3B729794B1647978be2d7F#code ``` function derivedBalance(address account) public view returns (uint) { return balanceOf[account]; } ``` ### Locker #### delegate voting power ``` await sendTransaction(task, "lpDepositor", "setAddresses", [ info.LPF, // _dou, task.deployments.veDepositor.address, // _dddxdou, task.deployments.doubleVoter.address, // _doubleVoter, task.deployments.feeDistributor.address, // _feeDistributor task.deployments.pVeloStaking.address, // _pVeloStaking, task.signerAddr, // _tokenWhitelister, task.deployments.lpDepositToken.address, // _depositToken, task.signerAddr, // _teamRewards, task.signerAddr, // _investorsRewards ]); ``` #### locker fixed 16 weeks - vlCVX Multiple locks - vlDOU ### Reward ditribution stream - Rebase: Velo ```mermaid sequenceDiagram actor user user ->> veDepositor:claimFromVeDistributor() veDepositor->>veDistributor:claim() veDepositor-->>votingEscrow:locked() veDepositor->>treasury:depositFee() ``` - Emission: Velo ```mermaid sequenceDiagram actor user user ->> lpDepositor:deposit() user ->> lpDepositor:withdraw() user ->> lpDepositor:getReward() user ->> lpDepositor:transfer() user ->> lpDepositor:claimLockerRewards() critical _updateIntegrals() lpDepositor->>gauge:getReward(velo) Note right of lpDepositor: calculate and update reward end ``` - Bribes: Any ```mermaid sequenceDiagram actor user user ->> lpDepositor:claimLockerRewards() critical _updateIntegrals() lpDepositor->>gauge:getReward(velo) end lpDepositor->>bribes:external:getReward(any) lpDepositor->>bribes:internal:getReward(any) lpDepositor->>treasury:depositFee() ```