-
Notifications
You must be signed in to change notification settings - Fork 42
add permissionless lending features #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for opening the PR. There are some things to be addressed:
- Cross shard deployment of Lending pool is not supported in this model. Please go through this for understanding how to deploy to different shards
- One of the acceptance criteria was to not change existing functionality but the code introduced here, has empty functions.
- There is a deadlock between constructor of global ledger contract and lending pool factory contract, according to the current implementation introduced I would need global ledger to deploy the factory but to deploy the factory I need the global ledger as well, which is not possible.
Please address these and let us know if you have any issues on implementing the given functionalities.
Also, please mention the issue you are solving, by linking it to this PR.
hello @gitshreevatsa thanks for your update on some of things I need to address on my issue assigned. I have already made the changes to reflect your guidance and the things we need to address as follows; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please review the changes mentioned
import "@nilfoundation/smart-contracts/contracts/NilTokenBase.sol"; | ||
|
||
// Axelar Gateway Interface for cross-chain communication | ||
interface IAxelarGateway { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think axelar gateway is something that works over here. As we support our own inter shard communication system. I would prefer you to go through our docs of cross shard communication: here
You would have to deploy a lending pool using the asyncDeploy and then call a registration function.
address gateway, | ||
address token | ||
) external returns (address) { | ||
LendingPool newPool = new LendingPool(globalLedger, lendingPoolChain, gateway, msg.sender, token); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method wouldn't work if the contracts are deployed on different shards
token = _token; | ||
} | ||
|
||
function deposit(uint256 amount) external { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that you have changed the deposit function such that it is not backward compatible. One of the main criterias is to make sure backward compatiblity, these changes don't let the interaction remain same.
hello @gitshreevatsa, the changes you suggested have already made in the code such as using the default inter shard communication system, deploy a lending pool using the asyncDeploy and then call a registration function and also backward compatibility. hope this will function, thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for some changes, I have left some comments to align on completing this issue.
} | ||
|
||
function deployLendingPool() external returns (address) { | ||
LendingPool newPool = new LendingPool( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned previously, this method would just deploy on the same shard but not on other shards. The requirement is to use asyncDeploy
and deploy into other shards based on a round robin fashion, have a counter which doesn't exceed 4 and on every deployment it increments so that you have deploy onto different shards.
address poolAddress = address(newPool); | ||
|
||
// Asynchronously register the new lending pool with the GlobalLedger | ||
globalLedger.asyncCall( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I doubt this is the signature of asyncCall. You can see the signature here
@@ -5,22 +5,15 @@ import "@nilfoundation/smart-contracts/contracts/Nil.sol"; | |||
import "@nilfoundation/smart-contracts/contracts/NilTokenBase.sol"; | |||
|
|||
/// @title LendingPool | |||
/// @dev The LendingPool contract facilitates lending and borrowing of tokens and handles collateral management. | |||
/// It interacts with other contracts such as GlobalLedger, InterestManager, and Oracle for tracking deposits, calculating interest, and fetching token prices. | |||
/// @dev A contract for decentralized lending and borrowing, integrating GlobalLedger, InterestManager, and Oracle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This contracts still lacks repayment so it wouldn't support backward compatiblity, please add the repayment functions that are associated. They are currently present in the academy.
} | ||
|
||
/// @title LendingPool - Individual lending pools for decentralized lending | ||
contract LendingPool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the extra contract written here when there is already LendingPool.sol
in another file. And moreover this contracts lacks a lot of funtionalities. This seems extra contract. You can remove this
return userDeposits[user]; | ||
} | ||
|
||
function deployLendingPool() external { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused why does the GlobalLedger have deployLendingPool
function while it had to be the Factory contract that should have this. Please explain me the arcitecutre that you intend to build, it would be of good discussion to know your thoughts!
Hi @gitshreevatsa I have made some changes to align with the guidance you recommended; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making some changes from previous comments. I think the issue requires these steps:
- Don't change anything with respect to LendingPool contract(currently in the
nil
repository, the forked repository has some changes). - After
asyncDeploy
in the LendingPool Factory contract, please add aasyncCall
to theGlobalLedger
. - Change the
GlobalLedger
to have a role based access function in which only the factory can set the lending pool address and then use that modifier for recordLoan, recordDeposit and recordRepay - Also, please create a new Hardhat Task for testing, it would be easier to test.
|
||
// @title GlobalLedger | ||
// @dev Tracks deposits, loans, and repayments across LendingPool contracts | ||
contract GlobalLedger { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While there already exists CollateralManager contract, why would we need this GlobalLedger Contract?
/// @param success Indicates if the loan clearing was successful. | ||
/// @param returnData The collateral data returned from the GlobalLedger. | ||
/// @param context The context containing borrower and collateral token. | ||
function releaseCollateral( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without these functions, thee=re would be no colateral release, please dont change them
} | ||
|
||
/// @notice Deploys a new LendingPool contract to a shard | ||
function deployLendingPool() external { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the deployment of the contract, there should be a function which calls the globalLedger to register the lending pool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well noted Sir, I will make changes
Hello @gitshreevatsa, hope you are well. The cha nges you requested have made some effort to ensure the project fuction smoothly.Below are the changes made; Kind regards. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for making these changes, there are a few things to address and things are going forward!
shardCounter = (shardCounter + 1) % 4; // Cycle through shards | ||
|
||
// Async call to register LendingPool in GlobalLedger | ||
(bool success, ) = globalLedger.call( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The call has to be made via asyncCall because when the global ledger is on different shard compared to the shard where Factory is deployed, this call would fail to work. Just include Nil.asyncCall and no need to resolve it!
@@ -0,0 +1,42 @@ | |||
const { task } = require("hardhat/config"); | |||
|
|||
task("deploy-lending-pool", "Deploys a new LendingPool contract and registers it in GlobalLedger") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check the run-lending-protocol
task, in that you can see that the contracts are in fact deployed rather than taken from the params.
const factory = LendingPoolFactory.attach(factoryAddress); | ||
|
||
// Deploy LendingPool via factory | ||
const tx = await factory.deployLendingPool(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usage of ethers wouldn't work completely with =nil; as we have some differences while calling contracts. Please use niljs. You can learn more about niljs here.
|
||
/// @title GlobalLedger | ||
/// @dev Tracks deposits, loans, and repayments across LendingPool contracts | ||
contract GlobalLedger is Ownable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we already have the GlobalLedger
inside CollateralManager.sol
why did you want to write an amended contract? I would advise you to use the GlobalLedger
inside CollateralManager.sol
as it has a lot of functionality that would support backward compatiblity. So only thing you would have to change in GlobalLedger
inside CollateralManager.sol
would be add factory based role access to it, as your code for factory based role access looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @gitshreevatsa, thanks for the update. I have made some changes on the code incuding removing Globalledger.sol to avoid duplicate and others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the changes mentioned.
|
||
// Assuming Nil provides an alternative method for cross-shard calls | ||
// Using Nil.asyncCall to interact with GlobalLedger | ||
(bool success, ) = address(Nil).call( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change this to use Nil.asyncCall
with the correct signature
const { task } = require("hardhat/config"); | ||
const { Nil } = require("niljs"); | ||
|
||
task("deploy-lending-pool", "Deploys a new LendingPool and registers in GlobalLedger") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The contracts have to deployed inside the task and not be taken as arguments of the script.
eth, | ||
} = taskArgs; | ||
|
||
const nil = new Nil(hre.network.config.nilProviderUrl); // configure `nilProviderUrl` in hardhat.config.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please go through run-lending-pool
task file once to see how a client is initiated, how a smart contract/account is deployed and how transactions are sent to the network. This implementation wouldn't work.
hello @gitshreevatsa , some changes made as guided. Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address the comments mentioned. Thank you for making previous changes.
FaucetClient, | ||
generateSmartAccount, | ||
waitTillCompleted, | ||
Contract, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no class named Contract
that is exposed in niljs
|
||
// Cross-shard async call to GlobalLedger to register the new LendingPool | ||
Nil.asyncCall( | ||
0, // Shard ID for GlobalLedger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A contract cannot be deployed on shard 0. Please change this to the respective shard id of global ledger that you deploy in the script
[deployer, user] = await ethers.getSigners(); | ||
|
||
// Deploy LendingPoolFactory contract | ||
const LendingPoolFactory = await ethers.getContractFactory("LendingPoolFactory"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would have to use niljs as I had previously mentioned.
console.log(`Oracle deployed: ${oracle}`); | ||
|
||
// Step 3: Deploy LendingPool with linked contracts | ||
const { address: lendingPool, hash: lendingPoolHash } = await deployer.deployContract({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to deploy the lending pool via the factory not via a separate script
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well noted Sir. Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good Afternoon @gitshreevatsa,
The changes you guided from my code have tried to address it, am requesting if you can check on it. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for implementing the changes. Please address these comments
constructorArgs | ||
); | ||
|
||
address poolAddress = INilAsync(NIL_ASYNC_PRECOMPILE).asyncDeploy( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can directly use Nil.sol than creating an interface. Please use that
args: [], | ||
}); | ||
|
||
const { hash: deployHash } = await deployer.execute({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be deloyer.sendTransaction not execute
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @gitshreevatsa ,
I have address the changes requested, thanks.
…ransaction handling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for making changes. Please address the issues with respect to Factory contract and the file structures.
uint8 public shardCounter; | ||
|
||
/// @dev Nil precompile interface for async deploy/call | ||
Nil constant nil = Nil(0x0000000000000000000000000000000000008003); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You dont need to do this. Nil.sol directly gives you access to asyncCall or asyncDeploy
0 | ||
); | ||
|
||
require(success, "asyncCall to GlobalLedger failed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You dont get a response back from asyncCall precompile
@@ -0,0 +1,113 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file present inside comtracts?
0, | ||
0, | ||
bytecode, | ||
0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally the salt argument shouldn,t be set 0. You can instead use a counter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @gitshreevatsa for your feedback ,
I have address the issues with respect to Factory contract and the file structures.
#Description of my work
I have implemented the followings in the contract system;
Closes #613