# 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()
```