feat: add fluid connector

This commit is contained in:
Shriya Tyagi 2023-12-24 15:51:25 +04:00
parent 156749cbaa
commit 24ffd46db7
5 changed files with 322 additions and 8 deletions

View File

@ -0,0 +1,14 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
contract Events {
event LogOperate (
address vaultAddress,
uint256 nftId,
int256 newCol,
int256 newDebt,
address to,
uint256 getId,
uint256 setId
);
}

View File

@ -0,0 +1,47 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
interface IVault {
/// @dev Single function which handles supply, withdraw, borrow & payback
/// @param nftId_ NFT ID for interaction. If 0 then create new NFT/position.
/// @param newCol_ new collateral. If positive then deposit, if negative then withdraw, if 0 then do nohing
/// @param newDebt_ new debt. If positive then borrow, if negative then payback, if 0 then do nohing
/// @param to_ address where withdraw or borrow should go. If address(0) then msg.sender
/// @return nftId_ if 0 then this returns the newly created NFT Id else returns the same NFT ID
/// @return final supply amount. Mainly if max withdraw using type(int).min then this is useful to get perfect amount else remain same as newCol_
/// @return final borrow amount. Mainly if max payback using type(int).min then this is useful to get perfect amount else remain same as newDebt_
function operate(
uint256 nftId_, // if 0 then new position
int256 newCol_, // if negative then withdraw
int256 newDebt_, // if negative then payback
address to_ // address at which the borrow & withdraw amount should go to. If address(0) then it'll go to msg.sender
)
external
payable
returns (
uint256, // nftId_
int256, // final supply amount if - then withdraw
int256 // final borrow amount if - then payback
);
struct ConstantViews {
address liquidity;
address factory;
address adminImplementation;
address secondaryImplementation;
address supplyToken;
address borrowToken;
uint8 supplyDecimals;
uint8 borrowDecimals;
uint vaultId;
bytes32 liquidityTotalSupplySlot;
bytes32 liquidityTotalBorrowSlot;
bytes32 liquiditySupplyExchangePriceSlot;
bytes32 liquidityBorrowExchangePriceSlot;
bytes32 liquidityUserSupplySlot;
bytes32 liquidityUserBorrowSlot;
}
function constantsView() external view returns (ConstantViews memory constantsView_);
}

View File

@ -0,0 +1,98 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
/**
* @title Fluid.
* @dev Lending & Borrowing.
*/
import {Stores} from "../../common/stores.sol";
import {TokenInterface} from "../../common/interfaces.sol";
import {Events} from "./events.sol";
import {IVault} from "./interface.sol";
abstract contract FluidConnector is Events, Stores {
/**
* @dev Returns Eth address
*/
function getEthAddr() internal pure returns (address) {
return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
}
/**
* @dev Deposit, borrow, payback and withdraw asset from the vault.
* @notice Single function which handles supply, withdraw, borrow & payback
* @param vaultAddress_ Vault address.
* @param nftId_ NFT ID for interaction. If 0 then create new NFT/position.
* @param newCol_ New collateral. If positive then deposit, if negative then withdraw, if 0 then do nothing
* @param newDebt_ New debt. If positive then borrow, if negative then payback, if 0 then do nothing
* @param to_ Address where withdraw or borrow should go. If address(0) then msg.sender
* @param getId_ ID to retrieve NFT ID.
* @param setId_ ID stores the NFT ID generated.
*/
function operate(
address vaultAddress_,
uint256 nftId_,
int256 newCol_,
int256 newDebt_,
address to_,
uint256 getId_,
uint256 setId_
)
external
payable
returns (string memory _eventName, bytes memory _eventParam)
{
nftId_ = getUint(getId_, nftId_);
IVault vault_ = IVault(vaultAddress_);
IVault.ConstantViews memory vaultDetails_ = vault_.constantsView();
bool isSupplyTokenEth_ = vaultDetails_.supplyToken == getEthAddr();
bool isBorrowTokenEth_ = vaultDetails_.borrowToken == getEthAddr();
if (newCol_ > 0 && !isSupplyTokenEth_) {
TokenInterface(vaultDetails_.supplyToken).approve(
vaultAddress_,
uint256(newCol_)
);
}
if (newDebt_ < 0 && !isBorrowTokenEth_) {
TokenInterface(vaultDetails_.borrowToken).approve(
vaultAddress_,
uint256(-1 * newDebt_)
);
}
uint256 colEthAmount_ = isSupplyTokenEth_ && newCol_ > 0
? uint256(newCol_)
: 0;
uint256 debtEthAmount_ = isBorrowTokenEth_ && newDebt_ < 0
? uint256(-1 * newDebt_)
: 0;
(nftId_, newCol_, newDebt_) = vault_.operate{
value: colEthAmount_ + debtEthAmount_
}(nftId_, newCol_, newDebt_, to_);
setUint(setId_, nftId_);
_eventName = "LogOperate(address,uint256,int256,int256,address,uint256,uint256)";
_eventParam = abi.encode(
vaultAddress_,
nftId_,
newCol_,
newDebt_,
to_,
getId_,
setId_
);
}
}
contract ConnectV2Fluid is FluidConnector {
string public constant name = "Fluid-v1.0";
}

168
package-lock.json generated
View File

@ -8,11 +8,14 @@
"name": "dsa-connectors-2.0",
"version": "1.0.0",
"dependencies": {
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@openzeppelin/contracts": "^4.9.5",
"@typechain/ethers-v5": "^10.2.1",
"@typechain/hardhat": "^6.1.6",
"bignumber.js": "^4.0.4",
"dotenv": "^16.3.1",
"prettier": "^3.1.1",
"prettier-plugin-solidity": "^1.2.0",
"ts-node": "^10.9.2",
"web3": "^4.3.0"
},
@ -1390,6 +1393,15 @@
"node": ">= 10"
}
},
"node_modules/@nomiclabs/hardhat-ethers": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz",
"integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==",
"peerDependencies": {
"ethers": "^5.0.0",
"hardhat": "^2.0.0"
}
},
"node_modules/@openzeppelin/contracts": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.5.tgz",
@ -1529,6 +1541,14 @@
"node": ">=6"
}
},
"node_modules/@solidity-parser/parser": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz",
"integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==",
"dependencies": {
"antlr4ts": "^0.5.0-alpha.4"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
@ -1800,6 +1820,11 @@
"node": ">=4"
}
},
"node_modules/antlr4ts": {
"version": "0.5.0-alpha.4",
"resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
"integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@ -3839,19 +3864,65 @@
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
"integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
"bin": {
"prettier": "bin-prettier.js"
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=10.13.0"
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-plugin-solidity": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.2.0.tgz",
"integrity": "sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==",
"dependencies": {
"@solidity-parser/parser": "^0.16.2",
"semver": "^7.5.4",
"solidity-comments-extractor": "^0.0.7"
},
"engines": {
"node": ">=16"
},
"peerDependencies": {
"prettier": ">=2.3.0"
}
},
"node_modules/prettier-plugin-solidity/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prettier-plugin-solidity/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/prettier-plugin-solidity/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -4141,6 +4212,11 @@
"semver": "bin/semver"
}
},
"node_modules/solidity-comments-extractor": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
"integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw=="
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -4549,6 +4625,20 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/typechain/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/typescript": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
@ -6232,6 +6322,12 @@
"integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==",
"optional": true
},
"@nomiclabs/hardhat-ethers": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.3.tgz",
"integrity": "sha512-YhzPdzb612X591FOe68q+qXVXGG2ANZRvDo0RRUtimev85rCrAlv/TLMEZw5c+kq9AbzocLTVX/h2jVIFPL9Xg==",
"requires": {}
},
"@openzeppelin/contracts": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.5.tgz",
@ -6335,6 +6431,14 @@
"tslib": "^1.9.3"
}
},
"@solidity-parser/parser": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz",
"integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==",
"requires": {
"antlr4ts": "^0.5.0-alpha.4"
}
},
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
@ -6541,6 +6645,11 @@
"color-convert": "^1.9.0"
}
},
"antlr4ts": {
"version": "0.5.0-alpha.4",
"resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz",
"integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ=="
},
"anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@ -8013,9 +8122,42 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
"integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw=="
},
"prettier-plugin-solidity": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.2.0.tgz",
"integrity": "sha512-fgxcUZpVAP+LlRfy5JI5oaAkXGkmsje2VJ5krv/YMm+rcTZbIUwFguSw5f+WFuttMjpDm6wB4UL7WVkArEfiVA==",
"requires": {
"@solidity-parser/parser": "^0.16.2",
"semver": "^7.5.4",
"solidity-comments-extractor": "^0.0.7"
},
"dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
},
"queue-microtask": {
"version": "1.2.3",
@ -8231,6 +8373,11 @@
}
}
},
"solidity-comments-extractor": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
"integrity": "sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw=="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -8516,6 +8663,11 @@
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="
}
}
},

View File

@ -8,11 +8,14 @@
"typechain": "^8.3.2"
},
"dependencies": {
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@openzeppelin/contracts": "^4.9.5",
"@typechain/ethers-v5": "^10.2.1",
"@typechain/hardhat": "^6.1.6",
"bignumber.js": "^4.0.4",
"dotenv": "^16.3.1",
"prettier": "^3.1.1",
"prettier-plugin-solidity": "^1.2.0",
"ts-node": "^10.9.2",
"web3": "^4.3.0"
}