mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
feat: implemented the seize function
This commit is contained in:
parent
b3f7c1e883
commit
7ebd95e22e
|
@ -27,6 +27,20 @@ interface ILendingPoolCollateralManager {
|
||||||
bool receiveAToken
|
bool receiveAToken
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Emitted when the collateral of a user has been seized
|
||||||
|
* @param user The user whose collateral has been seized
|
||||||
|
* @param asset The addresse of the underlying asset to seize
|
||||||
|
* @param to The address that will receive the funds
|
||||||
|
* @param amount The amount seized
|
||||||
|
**/
|
||||||
|
event Seized(
|
||||||
|
address indexed user,
|
||||||
|
address indexed to,
|
||||||
|
address indexed asset,
|
||||||
|
uint256 amount
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Emitted when a reserve is disabled as collateral for an user
|
* @dev Emitted when a reserve is disabled as collateral for an user
|
||||||
* @param reserve The address of the reserve
|
* @param reserve The address of the reserve
|
||||||
|
@ -57,4 +71,16 @@ interface ILendingPoolCollateralManager {
|
||||||
uint256 debtToCover,
|
uint256 debtToCover,
|
||||||
bool receiveAToken
|
bool receiveAToken
|
||||||
) external returns (uint256, string memory);
|
) external returns (uint256, string memory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Function to seize the collateral of a user. Only whitelisters of the user can call this function
|
||||||
|
* @param user The user whose collateral has been seized
|
||||||
|
* @param assets The addresses of the underlying assets to seize
|
||||||
|
* @param to The address that will receive the funds
|
||||||
|
**/
|
||||||
|
function seize(
|
||||||
|
address user,
|
||||||
|
address[] calldata assets,
|
||||||
|
address to
|
||||||
|
) external returns (uint256, string memory);
|
||||||
}
|
}
|
||||||
|
|
20
contracts/interfaces/IPermissionedLendingPool.sol
Normal file
20
contracts/interfaces/IPermissionedLendingPool.sol
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-License-Identifier: agpl-3.0
|
||||||
|
pragma solidity 0.6.12;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
|
||||||
|
import {ILendingPool} from './ILendingPool.sol';
|
||||||
|
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||||
|
|
||||||
|
interface IPermissionedLendingPool is ILendingPool {
|
||||||
|
/**
|
||||||
|
* @dev Function to seize the collateral of a user. Only whitelisters of the user can call this function
|
||||||
|
* @param assets The addresses of the underlying assets to seize
|
||||||
|
* @param to The address that will receive the funds
|
||||||
|
**/
|
||||||
|
function seize(
|
||||||
|
address user,
|
||||||
|
address[] calldata assets,
|
||||||
|
address to
|
||||||
|
) external;
|
||||||
|
}
|
|
@ -67,6 +67,29 @@ contract LendingPoolCollateralManager is
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Function to seize the collateral of a user. Only whitelisters of the user can call this function
|
||||||
|
* @param assets The addresses of the underlying assets to seize
|
||||||
|
* @param to The address that will receive the funds
|
||||||
|
**/
|
||||||
|
function seize(
|
||||||
|
address user,
|
||||||
|
address[] calldata assets,
|
||||||
|
address to
|
||||||
|
) external override returns (uint256, string memory) {
|
||||||
|
for (uint256 i = 0; i < assets.length; i++) {
|
||||||
|
address asset = assets[i];
|
||||||
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
|
IAToken aToken = IAToken(reserve.aTokenAddress);
|
||||||
|
uint256 userBalance = aToken.balanceOf(user);
|
||||||
|
|
||||||
|
reserve.updateState();
|
||||||
|
reserve.updateInterestRates(asset, address(aToken), 0, userBalance);
|
||||||
|
aToken.burn(user, to, userBalance, reserve.liquidityIndex);
|
||||||
|
emit Seized(user, to, asset, userBalance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Function to liquidate a position if its Health Factor drops below 1
|
* @dev Function to liquidate a position if its Health Factor drops below 1
|
||||||
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||||
|
|
|
@ -4,6 +4,8 @@ pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import {LendingPool} from './LendingPool.sol';
|
import {LendingPool} from './LendingPool.sol';
|
||||||
import {IPermissionManager} from '../../interfaces/IPermissionManager.sol';
|
import {IPermissionManager} from '../../interfaces/IPermissionManager.sol';
|
||||||
|
import {IPermissionedLendingPool} from '../../interfaces/IPermissionedLendingPool.sol';
|
||||||
|
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||||
|
|
||||||
|
@ -12,7 +14,7 @@ import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||||
* @notice This smart contracts adds a permission layer to the LendingPool contract to enable whitelisting of users interacting with it
|
* @notice This smart contracts adds a permission layer to the LendingPool contract to enable whitelisting of users interacting with it
|
||||||
* @author Aave
|
* @author Aave
|
||||||
**/
|
**/
|
||||||
contract PermissionedLendingPool is LendingPool {
|
contract PermissionedLendingPool is IPermissionedLendingPool, LendingPool {
|
||||||
//identifier for the permission manager contract in the addresses provider
|
//identifier for the permission manager contract in the addresses provider
|
||||||
bytes32 public constant PERMISSION_MANAGER = keccak256('PERMISSION_MANAGER');
|
bytes32 public constant PERMISSION_MANAGER = keccak256('PERMISSION_MANAGER');
|
||||||
|
|
||||||
|
@ -25,6 +27,11 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modifier onlyUserPermissionAdmin(address user) {
|
||||||
|
require(_isPermissionAdminOf(user, msg.sender), Errors.PLP_INVALID_PERMISSION_ADMIN);
|
||||||
|
_;
|
||||||
|
}
|
||||||
|
|
||||||
modifier onlyValidPermissionAdmin(address user) {
|
modifier onlyValidPermissionAdmin(address user) {
|
||||||
require(_permissionAdminValid(user), Errors.PLP_INVALID_PERMISSION_ADMIN);
|
require(_permissionAdminValid(user), Errors.PLP_INVALID_PERMISSION_ADMIN);
|
||||||
_;
|
_;
|
||||||
|
@ -68,7 +75,13 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
address onBehalfOf,
|
address onBehalfOf,
|
||||||
uint16 referralCode
|
uint16 referralCode
|
||||||
) public virtual override onlyDepositors(onBehalfOf) onlyValidPermissionAdmin(onBehalfOf) {
|
)
|
||||||
|
public
|
||||||
|
virtual
|
||||||
|
override(ILendingPool, LendingPool)
|
||||||
|
onlyDepositors(onBehalfOf)
|
||||||
|
onlyValidPermissionAdmin(onBehalfOf)
|
||||||
|
{
|
||||||
super.deposit(asset, amount, onBehalfOf, referralCode);
|
super.deposit(asset, amount, onBehalfOf, referralCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +100,13 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
address asset,
|
address asset,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
address to
|
address to
|
||||||
) public virtual override onlyDepositors(msg.sender) returns (uint256) {
|
)
|
||||||
|
public
|
||||||
|
virtual
|
||||||
|
override(ILendingPool, LendingPool)
|
||||||
|
onlyDepositors(msg.sender)
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
return super.withdraw(asset, amount, to);
|
return super.withdraw(asset, amount, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +131,13 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
uint256 interestRateMode,
|
uint256 interestRateMode,
|
||||||
uint16 referralCode,
|
uint16 referralCode,
|
||||||
address onBehalfOf
|
address onBehalfOf
|
||||||
) public virtual override onlyBorrowers(onBehalfOf) onlyValidPermissionAdmin(onBehalfOf) {
|
)
|
||||||
|
public
|
||||||
|
virtual
|
||||||
|
override(ILendingPool, LendingPool)
|
||||||
|
onlyBorrowers(onBehalfOf)
|
||||||
|
onlyValidPermissionAdmin(onBehalfOf)
|
||||||
|
{
|
||||||
super.borrow(asset, amount, interestRateMode, referralCode, onBehalfOf);
|
super.borrow(asset, amount, interestRateMode, referralCode, onBehalfOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +161,7 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
)
|
)
|
||||||
public
|
public
|
||||||
virtual
|
virtual
|
||||||
override
|
override(ILendingPool, LendingPool)
|
||||||
onlyBorrowers(onBehalfOf)
|
onlyBorrowers(onBehalfOf)
|
||||||
onlyValidPermissionAdmin(onBehalfOf)
|
onlyValidPermissionAdmin(onBehalfOf)
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
|
@ -152,7 +177,7 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
function swapBorrowRateMode(address asset, uint256 rateMode)
|
function swapBorrowRateMode(address asset, uint256 rateMode)
|
||||||
public
|
public
|
||||||
virtual
|
virtual
|
||||||
override
|
override(ILendingPool, LendingPool)
|
||||||
onlyBorrowers(msg.sender)
|
onlyBorrowers(msg.sender)
|
||||||
onlyValidPermissionAdmin(msg.sender)
|
onlyValidPermissionAdmin(msg.sender)
|
||||||
{
|
{
|
||||||
|
@ -171,7 +196,7 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
function rebalanceStableBorrowRate(address asset, address user)
|
function rebalanceStableBorrowRate(address asset, address user)
|
||||||
public
|
public
|
||||||
virtual
|
virtual
|
||||||
override
|
override(ILendingPool, LendingPool)
|
||||||
onlyStableRateManagers
|
onlyStableRateManagers
|
||||||
{
|
{
|
||||||
super.rebalanceStableBorrowRate(asset, user);
|
super.rebalanceStableBorrowRate(asset, user);
|
||||||
|
@ -185,7 +210,7 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
|
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
|
||||||
public
|
public
|
||||||
virtual
|
virtual
|
||||||
override
|
override(ILendingPool, LendingPool)
|
||||||
onlyDepositors(msg.sender)
|
onlyDepositors(msg.sender)
|
||||||
onlyValidPermissionAdmin(msg.sender)
|
onlyValidPermissionAdmin(msg.sender)
|
||||||
{
|
{
|
||||||
|
@ -209,10 +234,41 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
address user,
|
address user,
|
||||||
uint256 debtToCover,
|
uint256 debtToCover,
|
||||||
bool receiveAToken
|
bool receiveAToken
|
||||||
) public virtual override onlyLiquidators onlyValidPermissionAdmin(msg.sender) {
|
)
|
||||||
|
public
|
||||||
|
virtual
|
||||||
|
override(ILendingPool, LendingPool)
|
||||||
|
onlyLiquidators
|
||||||
|
onlyValidPermissionAdmin(msg.sender)
|
||||||
|
{
|
||||||
super.liquidationCall(collateralAsset, debtAsset, user, debtToCover, receiveAToken);
|
super.liquidationCall(collateralAsset, debtAsset, user, debtToCover, receiveAToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Function to seize the collateral of a user. Only whitelisters of the user can call this function
|
||||||
|
* @param assets The addresses of the underlying assets to seize
|
||||||
|
* @param to The address that will receive the funds
|
||||||
|
**/
|
||||||
|
function seize(
|
||||||
|
address user,
|
||||||
|
address[] calldata assets,
|
||||||
|
address to
|
||||||
|
) public virtual override(IPermissionedLendingPool) onlyUserPermissionAdmin(user) whenNotPaused {
|
||||||
|
address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
|
||||||
|
|
||||||
|
//solium-disable-next-line
|
||||||
|
(bool success, bytes memory result) =
|
||||||
|
collateralManager.delegatecall(
|
||||||
|
abi.encodeWithSignature('seize(address,address[],address)', user, assets, to)
|
||||||
|
);
|
||||||
|
|
||||||
|
require(success, Errors.LP_LIQUIDATION_CALL_FAILED);
|
||||||
|
|
||||||
|
(uint256 returnCode, string memory returnMessage) = abi.decode(result, (uint256, string));
|
||||||
|
|
||||||
|
require(returnCode == 0, string(abi.encodePacked(returnMessage)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
|
* @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
|
||||||
* as long as the amount taken plus a fee is returned.
|
* as long as the amount taken plus a fee is returned.
|
||||||
|
@ -238,7 +294,7 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
address onBehalfOf,
|
address onBehalfOf,
|
||||||
bytes calldata params,
|
bytes calldata params,
|
||||||
uint16 referralCode
|
uint16 referralCode
|
||||||
) public virtual override {
|
) public virtual override(ILendingPool, LendingPool) {
|
||||||
//validating modes
|
//validating modes
|
||||||
for (uint256 i = 0; i < modes.length; i++) {
|
for (uint256 i = 0; i < modes.length; i++) {
|
||||||
if (modes[i] == uint256(DataTypes.InterestRateMode.NONE)) {
|
if (modes[i] == uint256(DataTypes.InterestRateMode.NONE)) {
|
||||||
|
@ -269,13 +325,20 @@ contract PermissionedLendingPool is LendingPool {
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 balanceFromBefore,
|
uint256 balanceFromBefore,
|
||||||
uint256 balanceToBefore
|
uint256 balanceToBefore
|
||||||
) public override {
|
) public override(ILendingPool, LendingPool) {
|
||||||
require(_isInRole(from, DataTypes.Roles.DEPOSITOR), Errors.VL_TRANSFER_NOT_ALLOWED);
|
require(_isInRole(from, DataTypes.Roles.DEPOSITOR), Errors.VL_TRANSFER_NOT_ALLOWED);
|
||||||
require(_isInRole(to, DataTypes.Roles.DEPOSITOR), Errors.VL_TRANSFER_NOT_ALLOWED);
|
require(_isInRole(to, DataTypes.Roles.DEPOSITOR), Errors.VL_TRANSFER_NOT_ALLOWED);
|
||||||
|
|
||||||
super.finalizeTransfer(asset, from, to, amount, balanceFromBefore, balanceToBefore);
|
super.finalizeTransfer(asset, from, to, amount, balanceFromBefore, balanceToBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _isPermissionAdminOf(address user, address caller) internal view returns (bool) {
|
||||||
|
return
|
||||||
|
IPermissionManager(_addressesProvider.getAddress(PERMISSION_MANAGER)).getUserPermissionAdmin(
|
||||||
|
user
|
||||||
|
) == caller;
|
||||||
|
}
|
||||||
|
|
||||||
function _isInRole(address user, DataTypes.Roles role) internal view returns (bool) {
|
function _isInRole(address user, DataTypes.Roles role) internal view returns (bool) {
|
||||||
return
|
return
|
||||||
IPermissionManager(_addressesProvider.getAddress(PERMISSION_MANAGER)).isInRole(
|
IPermissionManager(_addressesProvider.getAddress(PERMISSION_MANAGER)).isInRole(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user