makecredit delegation per debt token

This commit is contained in:
andyk 2020-09-14 13:52:05 +03:00
parent 1fbe84df49
commit c0c3133763
7 changed files with 176 additions and 103 deletions

View File

@ -29,9 +29,10 @@ interface ILendingPool {
event Withdraw(address indexed reserve, address indexed user, uint256 amount); event Withdraw(address indexed reserve, address indexed user, uint256 amount);
event BorrowAllowanceDelegated( event BorrowAllowanceDelegated(
address indexed asset,
address indexed fromUser, address indexed fromUser,
address indexed toUser, address indexed toUser,
address indexed asset, uint256 interestRateMode,
uint256 amount uint256 amount
); );
/** /**
@ -159,13 +160,15 @@ interface ILendingPool {
function delegateBorrowAllowance( function delegateBorrowAllowance(
address user, address user,
address asset, address asset,
uint256 interestRateMode,
uint256 amount uint256 amount
) external; ) external;
function getBorrowAllowance( function getBorrowAllowance(
address fromUser, address fromUser,
address toUser, address toUser,
address asset address asset,
uint256 interestRateMode
) external view returns (uint256); ) external view returns (uint256);
/** /**

View File

@ -48,6 +48,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
mapping(address => ReserveLogic.ReserveData) internal _reserves; mapping(address => ReserveLogic.ReserveData) internal _reserves;
mapping(address => UserConfiguration.Map) internal _usersConfig; mapping(address => UserConfiguration.Map) internal _usersConfig;
// debt token address => user who gives allowance => user who receives allowance => amount
mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance;
address[] internal _reservesList; address[] internal _reservesList;
@ -163,18 +164,28 @@ contract LendingPool is VersionedInitializable, ILendingPool {
function getBorrowAllowance( function getBorrowAllowance(
address fromUser, address fromUser,
address toUser, address toUser,
address asset address asset,
uint256 interestRateMode
) external override view returns (uint256) { ) external override view returns (uint256) {
return _borrowAllowance[fromUser][asset][toUser]; address debtToken = ReserveLogic.InterestRateMode.STABLE ==
ReserveLogic.InterestRateMode(interestRateMode)
? _reserves[asset].stableDebtTokenAddress
: _reserves[asset].variableDebtTokenAddress;
return _borrowAllowance[debtToken][fromUser][toUser];
} }
function delegateBorrowAllowance( function delegateBorrowAllowance(
address user, address user,
address asset, address asset,
uint256 interestRateMode,
uint256 amount uint256 amount
) external override { ) external override {
_borrowAllowance[msg.sender][asset][user] = amount; address debtToken = ReserveLogic.InterestRateMode.STABLE ==
emit BorrowAllowanceDelegated(msg.sender, user, asset, amount); ReserveLogic.InterestRateMode(interestRateMode)
? _reserves[asset].stableDebtTokenAddress
: _reserves[asset].variableDebtTokenAddress;
_borrowAllowance[debtToken][msg.sender][user] = amount;
emit BorrowAllowanceDelegated(asset, msg.sender, user, interestRateMode, amount);
} }
/** /**
@ -192,10 +203,19 @@ contract LendingPool is VersionedInitializable, ILendingPool {
uint16 referralCode, uint16 referralCode,
address onBehalfOf address onBehalfOf
) external override { ) external override {
ReserveLogic.ReserveData storage reserve = _reserves[asset];
if (onBehalfOf != msg.sender) { if (onBehalfOf != msg.sender) {
_borrowAllowance[onBehalfOf][asset][msg.sender] = _borrowAllowance[onBehalfOf][asset][msg address debtToken = ReserveLogic.InterestRateMode.STABLE ==
.sender] ReserveLogic.InterestRateMode(interestRateMode)
.sub(amount, Errors.BORROW_ALLOWANCE_ARE_NOT_ENOUGH); ? reserve.stableDebtTokenAddress
: reserve.variableDebtTokenAddress;
_borrowAllowance[debtToken][onBehalfOf][msg
.sender] = _borrowAllowance[debtToken][onBehalfOf][msg.sender].sub(
amount,
Errors.BORROW_ALLOWANCE_ARE_NOT_ENOUGH
);
} }
_executeBorrow( _executeBorrow(
ExecuteBorrowParams( ExecuteBorrowParams(
@ -204,7 +224,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
onBehalfOf, onBehalfOf,
amount, amount,
interestRateMode, interestRateMode,
_reserves[asset].aTokenAddress, reserve.aTokenAddress,
referralCode, referralCode,
true true
) )

View File

@ -111,7 +111,7 @@
}, },
"DefaultReserveInterestRateStrategy": { "DefaultReserveInterestRateStrategy": {
"buidlerevm": { "buidlerevm": {
"address": "0x2530ce07D254eA185E8e0bCC37a39e2FbA3bE548", "address": "0x626FdE749F9d499d3777320CAf29484B624ab84a",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {
@ -422,7 +422,7 @@
}, },
"StableDebtToken": { "StableDebtToken": {
"buidlerevm": { "buidlerevm": {
"address": "0x0Cf45557d25a4e4c0F1aC65EF6c48ae67c61a0E6", "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {
@ -432,7 +432,7 @@
}, },
"VariableDebtToken": { "VariableDebtToken": {
"buidlerevm": { "buidlerevm": {
"address": "0x7fAeC7791277Ff512c41CA903c177B2Ed952dDAc", "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {
@ -446,13 +446,13 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"buidlerevm": { "buidlerevm": {
"address": "0x33958cC3535Fc328369EAC2B2Bebd120D67C7fa1", "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
} }
}, },
"MockAToken": { "MockAToken": {
"buidlerevm": { "buidlerevm": {
"address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60", "address": "0x392E5355a0e88Bd394F717227c752670fb3a8020",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {
@ -472,7 +472,7 @@
}, },
"MockStableDebtToken": { "MockStableDebtToken": {
"buidlerevm": { "buidlerevm": {
"address": "0x392E5355a0e88Bd394F717227c752670fb3a8020", "address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {
@ -482,7 +482,7 @@
}, },
"MockVariableDebtToken": { "MockVariableDebtToken": {
"buidlerevm": { "buidlerevm": {
"address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460", "address": "0xEBAB67ee3ef604D5c250A53b4b8fcbBC6ec3007C",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}, },
"localhost": { "localhost": {

View File

@ -281,6 +281,7 @@ export const withdraw = async (
export const delegateBorrowAllowance = async ( export const delegateBorrowAllowance = async (
reserveSymbol: string, reserveSymbol: string,
amount: string, amount: string,
interestRateMode: string,
user: SignerWithAddress, user: SignerWithAddress,
receiver: tEthereumAddress, receiver: tEthereumAddress,
testEnv: TestEnv testEnv: TestEnv
@ -292,11 +293,9 @@ export const delegateBorrowAllowance = async (
await pool await pool
.connect(user.signer) .connect(user.signer)
.delegateBorrowAllowance(receiver, reserve, amountToDelegate.toString()); .delegateBorrowAllowance(receiver, reserve, interestRateMode, amountToDelegate.toString());
expect( expect(
( (await pool.getBorrowAllowance(user.address, receiver, reserve, interestRateMode)).toString()
await pool['getBorrowAllowance(address,address,address)'](user.address, receiver, reserve)
).toString()
).to.be.equal(amountToDelegate.toString(), 'borrowAllowance are set incorrectly'); ).to.be.equal(amountToDelegate.toString(), 'borrowAllowance are set incorrectly');
}; };

View File

@ -63,7 +63,7 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv
if (borrowRateMode) { if (borrowRateMode) {
if (borrowRateMode === 'none') { if (borrowRateMode === 'none') {
RateMode.None; rateMode = RateMode.None;
} else if (borrowRateMode === 'stable') { } else if (borrowRateMode === 'stable') {
rateMode = RateMode.Stable; rateMode = RateMode.Stable;
} else if (borrowRateMode === 'variable') { } else if (borrowRateMode === 'variable') {
@ -111,7 +111,7 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv
throw `Invalid amount to deposit into the ${reserve} reserve`; throw `Invalid amount to deposit into the ${reserve} reserve`;
} }
await delegateBorrowAllowance(reserve, amount, user, toUser, testEnv); await delegateBorrowAllowance(reserve, amount, rateMode, user, toUser, testEnv);
} }
break; break;

View File

@ -0,0 +1,130 @@
{
"title": "LendingPool: credit delegation",
"description": "Test cases for the credit delegation related functions.",
"stories": [
{
"description": "User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH on variable to user 4, user 4 borrows 1 WETH variable on behalf of user 0",
"actions": [
{
"name": "mint",
"args": {
"reserve": "WETH",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "WETH",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "WETH",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "delegateBorrowAllowance",
"args": {
"reserve": "WETH",
"amount": "2",
"user": "0",
"borrowRateMode": "variable",
"toUser": "4"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "4",
"onBehalfOf": "0",
"borrowRateMode": "variable"
},
"expected": "success"
}
]
},
{
"description": "User 4 trying to borrow 1 WETH stable on behalf of user 0, revert expected",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "4",
"onBehalfOf": "0",
"borrowRateMode": "stable"
},
"expected": "revert",
"revertMessage": "54"
}
]
},
{
"description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 3 WETH on behalf of user 0, revert expected",
"actions": [
{
"name": "delegateBorrowAllowance",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "0",
"toUser": "4"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "3",
"user": "4",
"onBehalfOf": "0",
"borrowRateMode": "variable"
},
"expected": "revert",
"revertMessage": "54"
}
]
},
{
"description": "User 0 delegates borrowing of 1 WETH on stable to user 2, user 2 borrows 1 WETH stable on behalf of user 0",
"actions": [
{
"name": "delegateBorrowAllowance",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "0",
"borrowRateMode": "stable",
"toUser": "2"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "2",
"onBehalfOf": "0",
"borrowRateMode": "stable"
},
"expected": "success"
}
]
}
]
}

View File

@ -955,85 +955,6 @@
"expected": "success" "expected": "success"
} }
] ]
},
{
"description": "User 0 deposits 1000 DAI, user 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 1 WETH on behalf of user 0",
"actions": [
{
"name": "mint",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "approve",
"args": {
"reserve": "DAI",
"user": "0"
},
"expected": "success"
},
{
"name": "deposit",
"args": {
"reserve": "DAI",
"amount": "1000",
"user": "0"
},
"expected": "success"
},
{
"name": "delegateBorrowAllowance",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "0",
"toUser": "4"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "4",
"onBehalfOf": "0",
"borrowRateMode": "variable"
},
"expected": "success"
}
]
},
{
"description": "User 0 delegates borrowing of 1 WETH to user 4, user 4 borrows 2 WETH on behalf of user 0, revert expected",
"actions": [
{
"name": "delegateBorrowAllowance",
"args": {
"reserve": "WETH",
"amount": "1",
"user": "0",
"toUser": "4"
},
"expected": "success"
},
{
"name": "borrow",
"args": {
"reserve": "WETH",
"amount": "2",
"user": "4",
"onBehalfOf": "0",
"borrowRateMode": "variable"
},
"expected": "revert",
"revertMessage": "54"
}
]
} }
] ]
} }