Skip to content

Commit

Permalink
Merge pull request #170 from Se7en-Seas/feat/add-lbtc-base
Browse files Browse the repository at this point in the history
Feat/add lbtc base
  • Loading branch information
mel0ndev authored Dec 2, 2024
2 parents 3fffbb9 + 0e39170 commit 5104039
Show file tree
Hide file tree
Showing 17 changed files with 3,173 additions and 91 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
cache/
out/
broadcast/
lib/LayerZero-v2

# Ignores development broadcast logs
!/broadcast
Expand All @@ -16,4 +17,4 @@ docs/

*.DS_Store
broadcast/*
leafs/TemporaryLeafs.json
leafs/TemporaryLeafs.json
1,948 changes: 1,948 additions & 0 deletions leafs/Base/LombardBTCStrategistLeafs.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion resources/ContractNames.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ contract ContractNames {
string public constant LombardBtcManagerName = "Lombard BTC Manager With Merkle Verification V0.0";
string public constant LombardBtcAccountantName = "Lombard BTC Accountant With Rate Providers V0.1";
string public constant LombardBtcTellerName = "Lombard BTC Teller With Multi Asset Support V0.1";
string public constant LombardBtcDecoderAndSanitizerName = "Lombard BTC Decoder and Sanitizer V0.0";
string public constant LombardBtcDecoderAndSanitizerName = "Lombard BTC Decoder and Sanitizer V0.1";
string public constant LombardBtcAerodromeDecoderAndSanitizerName =
"Lombard BTC Aerodrome Decoder and Sanitizer V0.0";
string public constant LombardBtcDelayedWithdrawer = "Lombard BTC Delayed Withdrawer V0.0";

string public constant EtherFiLiquidEthRolesAuthorityName = "EtherFi Liquid ETH RolesAuthority Version 0.0";
Expand Down
33 changes: 25 additions & 8 deletions script/DeployDecoderAndSanitizer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,50 @@ import {Deployer} from "src/helper/Deployer.sol";
import {MainnetAddresses} from "test/resources/MainnetAddresses.sol";
import {ContractNames} from "resources/ContractNames.sol";
import {PointFarmingDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/PointFarmingDecoderAndSanitizer.sol";
import {LombardBtcDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/LombardBtcDecoderAndSanitizer.sol";
import {AeraVaultFullDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/AeraVaultFullDecoderAndSanitizer.sol";


import {BoringDrone} from "src/base/Drones/BoringDrone.sol";

import "forge-std/Script.sol";
import "forge-std/StdJson.sol";
import "forge-std/Test.sol";

/**
* source .env && forge script script/DeployDecoderAndSanitizer.s.sol:DeployDecoderAndSanitizerScript --with-gas-price 30000000000 --broadcast --etherscan-api-key $ETHERSCAN_KEY --verify
* @dev Optionally can change `--with-gas-price` to something more reasonable
*/
contract DeployDecoderAndSanitizerScript is Script, ContractNames, MainnetAddresses {
contract DeployDecoderAndSanitizerScript is Script, Test, ContractNames, MainnetAddresses {
uint256 public privateKey;
Deployer public deployer = Deployer(deployerAddress);


address boringVault = 0x5401b8620E5FB570064CA9114fd1e135fd77D57c;

//address boringVault = 0x5401b8620E5FB570064CA9114fd1e135fd77D57c;
address boringVault = 0x1293b71644e7E55A692Cade85a0EDB381868AA7c;
//address boringVault = 0x1293b71644e7E55A692Cade85a0EDB381868AA7c;
address eEigen = 0xE77076518A813616315EaAba6cA8e595E845EeE9;

address liquidUsd = 0x08c6F91e2B681FaF5e17227F2a44C307b3C1364C;


function setUp() external {
privateKey = vm.envUint("ETHERFI_LIQUID_DEPLOYER");
vm.createSelectFork("mainnet");
//privateKey = vm.envUint("ETHERFI_LIQUID_DEPLOYER");
vm.createSelectFork("base");
}

function run() external {
bytes memory creationCode;
bytes memory constructorArgs;
privateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(privateKey);
console.log(privateKey);

// creationCode = type(AerodromeDecoderAndSanitizer).creationCode;
// constructorArgs =
// abi.encode(0xf0bb20865277aBd641a307eCe5Ee04E79073416C, 0x416b433906b1B72FA758e166e239c43d68dC6F29);
// deployer.deployContract(EtherFiLiquidEthAerodromeDecoderAndSanitizerName, creationCode, constructorArgs, 0);
creationCode = type(AerodromeDecoderAndSanitizer).creationCode;
address aerodromeNonFungiblePositionManager = 0x827922686190790b37229fd06084350E74485b72;
constructorArgs = abi.encode(boringVault, aerodromeNonFungiblePositionManager);
deployer.deployContract(LombardBtcAerodromeDecoderAndSanitizerName, creationCode, constructorArgs, 0);

// creationCode = type(OnlyKarakDecoderAndSanitizer).creationCode;
// constructorArgs = abi.encode(boringVault);
Expand All @@ -72,10 +81,18 @@ contract DeployDecoderAndSanitizerScript is Script, ContractNames, MainnetAddres
//constructorArgs = abi.encode(liquidUsd, uniswapV3NonFungiblePositionManager);
//deployer.deployContract(EtherFiLiquidUsdDecoderAndSanitizerName, creationCode, constructorArgs, 0);

//creationCode = type(LombardBtcDecoderAndSanitizer).creationCode;
//address baseUniswapV3NonFungiblePositionManager = 0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1;
//constructorArgs = abi.encode(boringVault, baseUniswapV3NonFungiblePositionManager);
//deployer.deployContract(LombardBtcDecoderAndSanitizerName, creationCode, constructorArgs, 0);

// new LombardBtcDecoderAndSanitizer(boringVault, baseUniswapV3NonFungiblePositionManager);

creationCode = type(AeraVaultFullDecoderAndSanitizer).creationCode;
constructorArgs = abi.encode(boringVault);
deployer.deployContract("Aera Vault Decoder and Santizier v0.0", creationCode, constructorArgs, 0);


vm.stopBroadcast();
}
}
101 changes: 101 additions & 0 deletions script/MerkleRootCreation/Base/CreateLBTCMerkleRoot.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol";
import {ERC20} from "@solmate/tokens/ERC20.sol";
import {Strings} from "lib/openzeppelin-contracts/contracts/utils/Strings.sol";
import {ERC4626} from "@solmate/tokens/ERC4626.sol";
import {ManagerWithMerkleVerification} from "src/base/Roles/ManagerWithMerkleVerification.sol";
import {MerkleTreeHelper} from "test/resources/MerkleTreeHelper/MerkleTreeHelper.sol";
import "forge-std/Script.sol";

/**
* source .env && forge script script/MerkleRootCreation/Base/CreateLBTCMerkleRoot.s.sol:CreateLBTCMerkleRootScript --rpc-url $BASE_RPC_URL
*/
contract CreateLBTCMerkleRootScript is Script, MerkleTreeHelper {
using FixedPointMathLib for uint256;

address public boringVault = 0x5401b8620E5FB570064CA9114fd1e135fd77D57c;
address public managerAddress = 0xcf38e37872748E3b66741A42560672A6cef75e9B;
address public accountantAddress = 0x28634D0c5edC67CF2450E74deA49B90a4FF93dCE;
address public rawDataDecoderAndSanitizer = 0xAae1c7546a8CCa32C0B02d8f4aB3A8a3d6E18070;
address public aerodromeDecoderAndSanitizer = 0xD657c2A871C467871b59d5992CD3bAb1634dd457;

function setUp() external {}

/**
* @notice Uncomment which script you want to run.
*/
function run() external {
/// NOTE Only have 1 function run at a time, otherwise the merkle root created will be wrong.
generateAdminStrategistMerkleRoot();
}

function generateAdminStrategistMerkleRoot() public {
setSourceChainName(base);
setAddress(false, base, "boringVault", boringVault);
setAddress(false, base, "managerAddress", managerAddress);
setAddress(false, base, "accountantAddress", accountantAddress);
setAddress(false, base, "rawDataDecoderAndSanitizer", rawDataDecoderAndSanitizer);

ManageLeaf[] memory leafs = new ManageLeaf[](128);

// ========================== UniswapV3 ==========================
address[] memory token0 = new address[](3);
token0[0] = getAddress(sourceChain, "cbBTC");
token0[1] = getAddress(sourceChain, "cbBTC");
token0[2] = getAddress(sourceChain, "LBTC");

address[] memory token1 = new address[](3);
token1[0] = getAddress(sourceChain, "LBTC");
token1[1] = getAddress(sourceChain, "WBTC");
token1[2] = getAddress(sourceChain, "WBTC");

_addUniswapV3Leafs(leafs, token0, token1);

// ========================== 1inch ==========================
address[] memory assets = new address[](4);
SwapKind[] memory kind = new SwapKind[](4);
assets[0] = getAddress(sourceChain, "cbBTC");
kind[0] = SwapKind.BuyAndSell;
assets[1] = getAddress(sourceChain, "LBTC");
kind[1] = SwapKind.BuyAndSell;
assets[2] = getAddress(sourceChain, "WBTC");
kind[2] = SwapKind.BuyAndSell;
assets[3] = getAddress(sourceChain, "AERO");
kind[3] = SwapKind.Sell;
//assets[3] = getAddress(sourceChain, "PENDLE");
//kind[3] = SwapKind.Sell;
_addLeafsFor1InchGeneralSwapping(leafs, assets, kind);

// ========================== Pendle ==========================
_addPendleMarketLeafs(leafs, getAddress(sourceChain, "pendle_LBTC_market_05_29_25"), true);

// ========================== Morpho ==========================
_addERC4626Leafs(leafs, ERC4626(getAddress(sourceChain, "gauntletCbBTCcore")));

// ========================= Aerodrome ========================
setAddress(true, sourceChain, "rawDataDecoderAndSanitizer", aerodromeDecoderAndSanitizer);
address[] memory _token0 = new address[](1);
_token0[0] = getAddress(sourceChain, "LBTC");
address[] memory _token1 = new address[](1);
_token1[0] = getAddress(sourceChain, "cbBTC");

address[] memory gauges = new address[](1);
gauges[0] = address(0);

_addVelodromeV3Leafs(
leafs, _token0, _token1, getAddress(sourceChain, "aerodromeNonFungiblePositionManager"), gauges
);

// ========================== Lombard ========================
// setAddress(true, sourceChain, "rawDataDecoderAndSanitizer", rawDataDecoderAndSanitizer);
// _addLombardBTCLeafs(leafs, getERC20(sourceChain, "cbBTC"), getERC20(sourceChain, "LBTC"));

string memory filePath = "./leafs/Base/LombardBTCStrategistLeafs.json";

bytes32[][] memory manageTree = _generateMerkleTree(leafs);

_generateLeafs(filePath, leafs, manageTree[manageTree.length - 1][0], manageTree);
}
}
10 changes: 10 additions & 0 deletions src/base/DecodersAndSanitizers/FluidDexFullDecoderAndSanitizer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {FluidDexDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/FluidDexDecoderAndSanitizer.sol";
import {BaseDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";

contract FluidDexFullDecoderAndSanitizer is FluidDexDecoderAndSanitizer {

constructor(address _boringVault) BaseDecoderAndSanitizer(_boringVault){}
}
14 changes: 13 additions & 1 deletion src/base/DecodersAndSanitizers/LombardBtcDecoderAndSanitizer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {StandardBridgeDecoderAndSanitizer} from
import {CompoundV3DecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/CompoundV3DecoderAndSanitizer.sol";
import {MerklDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/MerklDecoderAndSanitizer.sol";
import {LidoDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/LidoDecoderAndSanitizer.sol";
import {LombardBTCMinterDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/LombardBtcMinterDecoderAndSanitizer.sol";

contract LombardBtcDecoderAndSanitizer is
UniswapV3DecoderAndSanitizer,
Expand All @@ -59,7 +60,8 @@ contract LombardBtcDecoderAndSanitizer is
StandardBridgeDecoderAndSanitizer,
CompoundV3DecoderAndSanitizer,
MerklDecoderAndSanitizer,
LidoDecoderAndSanitizer
LidoDecoderAndSanitizer,
LombardBTCMinterDecoderAndSanitizer
{
constructor(address _boringVault, address _uniswapV3NonFungiblePositionManager)
BaseDecoderAndSanitizer(_boringVault)
Expand Down Expand Up @@ -170,4 +172,14 @@ contract LombardBtcDecoderAndSanitizer is
// Nothing to sanitize or return
return addressesFound;
}

function burn(uint256)
external
pure
override(UniswapV3DecoderAndSanitizer)
returns (bytes memory addressesFound)
{
// Nothing to sanitize or return
return addressesFound;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";
import {LombardBTCMinterDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/LombardBtcMinterDecoderAndSanitizer.sol";

contract LombardBTCFullMinterDecoderAndSanitizer is LombardBTCMinterDecoderAndSanitizer {

constructor(address _boringVault) BaseDecoderAndSanitizer(_boringVault) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,13 @@ abstract contract AaveV3DecoderAndSanitizer is BaseDecoderAndSanitizer {
// Nothing to sanitize or return
return addressesFound;
}

function claimRewards(address[] calldata /*assets*/, uint256 /*amount*/, address to, address /*reward*/)
external
pure
virtual
returns (bytes memory addressesFound)
{
addressesFound = abi.encodePacked(to);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";


abstract contract FluidDexDecoderAndSanitizer is BaseDecoderAndSanitizer {

/// @notice T2 and T3

/*
* @notice Vault T2 and T3 ((smart collateral, normal debt) / (normal collateral, smart debt))
* @notice T2 params on LHS, T3 on RHS -> T2ParamName/T3ParamName
* @dev These use the same function sig, so I'm just grouping them together
* @param nftId The ID of the NFT representing the vault position, use 0 for a new position
* @param newColToken0/newCol The change in collateral amount (positive for deposit, negative for withdrawal) * @param newColtoken1/newDebtToken0 The change in debt amount for token0 (positive for borrowing, negative for repayment)
* @param colSharesMinMax/newDebtToken1 The change in debt amount for token1 (positive for borrowing, negative for repayment)
* @param newDebt/debtSharesMinMax Min or max debt shares to mint or burn (positive for borrowing, negative for repayment)
* @param to The address to receive withdrawn collateral or borrowed tokens (if address(0), defaults to msg.sender)
*/
function operate(
uint256 /*nftId*/,
int256 /*newColToken0 / newCol*/,
int256 /*newColToken1 / newDebtToken0*/,
int256 /*colSharesMinMax / newDebtToken1*/,
int256 /*newDebt / debtSharesMinMax*/,
address to
) external pure virtual returns (bytes memory addressesFound) {
addressesFound = abi.encodePacked(to);
}

/*
* @param nftId The ID of the NFT representing the vault position, use 0 for a new position
* @param perfectColShares The change in collateral shares (positive for deposit, negative for withdrawal)
* @param colToken0MinMax_ min or max collateral amount of token0 to withdraw or deposit (positive for deposit, negative for withdrawal)
* @param colToken1MinMax_ min or max collateral amount of token1 to withdraw or deposit (positive for deposit, negative for withdrawal)
* @param newDebt_ The change in debt amount (positive for borrowing, negative for repayment)
* @param to_ The address to receive withdrawn collateral or borrowed tokens (if address(0), defaults to msg.sender)
*/
function operatePerfect(
uint256 /*nftId*/,
int256 /*perfectColShares*/,
int256 /*colToken0MinMax*/,
int256 /*colToken1MinMax*/,
int256 /*newDebt*/,
address to
) external pure virtual returns (bytes memory addressesFound) {
addressesFound = abi.encodePacked(to);
}


/// @notice T4 (smart collateral, smart debt)

/*
* @param nftId The ID of the NFT representing the vault position
* @param newColToken0 The change in collateral amount for token0 (positive for deposit, negative for withdrawal)
* @param newColToken1 The change in collateral amount for token1 (positive for deposit, negative for withdrawal)
* @param colSharesMinMax Min or max collateral shares to mint or burn (positive for deposit, negative for withdrawal)
* @param newDebtToken0 The change in debt amount for token0 (positive for borrowing, negative for repayment)
* @param newDebtToken1 The change in debt amount for token1 (positive for borrowing, negative for repayment)
* @param debtSharesMinMax Min or max debt shares to burn or mint (positive for borrowing, negative for repayment)
* @param to The address to receive funds (if address(0), defaults to msg.sender)
*/
function operate(
uint256 /*nftId*/,
int256 /*newColToken0*/,
int256 /*newColToken1*/,
int256 /*colSharesMinMax*/,
int256 /*newDebtToken0*/,
int256 /*newDebtToken1*/,
int256 /*debtSharesMinMax*/,
address to
) external pure virtual returns (bytes memory addressesFound) {
addressesFound = abi.encodePacked(to);
}

/*
* @param nftId_ The ID of the NFT representing the vault position
* @param perfectColShares_ The change in collateral shares (positive for deposit, negative for withdrawal)
* @param colToken0MinMax_ Min or max collateral amount of token0 to withdraw or deposit (positive for deposit, negative for withdrawal)
* @param colToken1MinMax_ Min or max collateral amount of token1 to withdraw or deposit (positive for deposit, negative for withdrawal)
* @param perfectDebtShares_ The change in debt shares (positive for borrowing, negative for repayment)
* @param debtToken0MinMax_ Min or max debt amount for token0 to borrow or payback (positive for borrowing, negative for repayment)
* @param debtToken1MinMax_ Min or max debt amount for token1 to borrow or payback (positive for borrowing, negative for repayment)
* @param to_ The address to receive funds (if address(0), defaults to msg.sender)
*/
function operatePerfect(
uint256 /*nftId*/,
int256 /*perfectColShares*/,
int256 /*colToken0MinMax*/,
int256 /*colToken1MinMax*/,
int256 /*perfectDebtShares*/,
int256 /*debtToken0MinMax*/,
int256 /*debtToken1MinMax*/,
address to
) external pure virtual returns (bytes memory addressesFound) {
addressesFound = abi.encodePacked(to);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer, DecoderCustomTypes} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";

abstract contract LombardBTCMinterDecoderAndSanitizer is BaseDecoderAndSanitizer {

/// @notice for permissioned users
function mint(address to, uint256 /*amount*/) external pure virtual returns (bytes memory addressesFound) {
addressesFound = abi.encodePacked(to);
}

/// @notice minting directly via LTBC contract
function mint(bytes calldata data, bytes calldata /*proofSignature*/) external pure virtual returns (bytes memory addressesFound) {
(, address to, , ,) = abi.decode(data, (uint256, address, uint64, bytes32, uint32));
addressesFound = abi.encodePacked(to);
}

/// @notice for minting using cbBTCPPM contract
function swapCBBTCToLBTC(uint256 /*amount*/) external pure virtual returns (bytes memory addressesFound) {
return addressesFound;
}

}
Loading

0 comments on commit 5104039

Please sign in to comment.