-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implementation of the Aave NFTs template
- Loading branch information
Showing
8 changed files
with
1,695 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
pragma solidity 0.6.12; | ||
// Copyright 2020 Keyko GmbH. | ||
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) | ||
// Code is Apache-2.0 and docs are CC-BY-4.0 | ||
|
||
import "../../Condition.sol"; | ||
import "../../../registry/DIDRegistry.sol"; | ||
import "../../../Common.sol"; | ||
import "./AaveCreditVault.sol"; | ||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; | ||
|
||
/** | ||
* @title Aave Borrow Credit Condition | ||
* @author Keyko | ||
* | ||
* @dev Implementation of the Aave Borrow Credit Condition | ||
*/ | ||
contract AaveBorrowCondition is Condition, Common { | ||
|
||
DIDRegistry internal didRegistry; | ||
AaveCreditVault internal aaveCreditVault; | ||
|
||
bytes32 public constant CONDITION_TYPE = keccak256("AaveBorrowCondition"); | ||
|
||
event Fulfilled( | ||
bytes32 indexed _agreementId, | ||
bytes32 indexed _did, | ||
bytes32 indexed _conditionId | ||
); | ||
|
||
/** | ||
* @notice initialize init the contract with the following parameters | ||
* @dev this function is called only once during the contract initialization. | ||
* @param _owner contract's owner account address | ||
* @param _conditionStoreManagerAddress condition store manager address | ||
* @param _didRegistryAddress DID Registry address | ||
*/ | ||
function initialize( | ||
address _owner, | ||
address _conditionStoreManagerAddress, | ||
address _didRegistryAddress | ||
) | ||
external | ||
initializer() | ||
{ | ||
require( | ||
_didRegistryAddress != address(0) && | ||
_conditionStoreManagerAddress != address(0), | ||
"Invalid address" | ||
); | ||
OwnableUpgradeable.__Ownable_init(); | ||
transferOwnership(_owner); | ||
conditionStoreManager = ConditionStoreManager( | ||
_conditionStoreManagerAddress | ||
); | ||
|
||
didRegistry = DIDRegistry(_didRegistryAddress); | ||
} | ||
|
||
function hashValues( | ||
bytes32 _did, | ||
address _borrower, | ||
address _assetToBorrow, | ||
uint256 _amount | ||
) | ||
public | ||
pure | ||
returns (bytes32) | ||
{ | ||
return | ||
keccak256( | ||
abi.encode( | ||
_did, | ||
_borrower, | ||
_assetToBorrow, | ||
_amount | ||
) | ||
); | ||
} | ||
|
||
function fulfill( | ||
bytes32 _agreementId, | ||
bytes32 _did, | ||
address _vaultAddress, | ||
address _assetToBorrow, | ||
uint256 _amount | ||
) | ||
external | ||
returns (ConditionStoreLibrary.ConditionState) | ||
{ | ||
AaveCreditVault vault = AaveCreditVault(_vaultAddress); | ||
vault.borrow(_assetToBorrow, _amount, msg.sender); | ||
|
||
bytes32 _id = | ||
generateId( | ||
_agreementId, | ||
hashValues(_did, msg.sender, _assetToBorrow, _amount) | ||
); | ||
|
||
ConditionStoreLibrary.ConditionState state = | ||
super.fulfill(_id, ConditionStoreLibrary.ConditionState.Fulfilled); | ||
|
||
return state; | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
contracts/conditions/defi/aave/AaveCollateralDepositCondition.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
pragma solidity 0.6.12; | ||
// Copyright 2020 Keyko GmbH. | ||
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) | ||
// Code is Apache-2.0 and docs are CC-BY-4.0 | ||
|
||
|
||
import "../../Condition.sol"; | ||
import "../../../registry/DIDRegistry.sol"; | ||
import "./AaveCreditVault.sol"; | ||
import "../../../Common.sol"; | ||
import "../../../templates/AaveCreditTemplate.sol"; | ||
import '@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol'; | ||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; | ||
|
||
/** | ||
* @title Aave Collateral Deposit Condition | ||
* @author Keyko | ||
* | ||
* @dev Implementation of the Lock Payment Condition | ||
* This condition allows to lock payment for multiple receivers taking | ||
* into account the royalties to be paid to the original creators in a secondary market. | ||
*/ | ||
contract AaveCollateralDepositCondition is Condition, Common, ReentrancyGuardUpgradeable { | ||
|
||
DIDRegistry internal didRegistry; | ||
AaveCreditVault internal aaveCreditVault; | ||
|
||
bytes32 public constant CONDITION_TYPE = keccak256("AaveCollateralDepositCondition"); | ||
|
||
event Fulfilled( | ||
bytes32 indexed _agreementId, | ||
bytes32 indexed _did, | ||
bytes32 indexed _conditionId | ||
); | ||
|
||
/** | ||
* @notice initialize init the contract with the following parameters | ||
* @dev this function is called only once during the contract initialization. | ||
* @param _owner contract's owner account address | ||
* @param _conditionStoreManagerAddress condition store manager address | ||
* @param _didRegistryAddress DID Registry address | ||
*/ | ||
function initialize( | ||
address _owner, | ||
address _conditionStoreManagerAddress, | ||
address _didRegistryAddress | ||
) external initializer() { | ||
|
||
require( | ||
_didRegistryAddress != address(0) && | ||
_conditionStoreManagerAddress != address(0), | ||
"Invalid address" | ||
); | ||
OwnableUpgradeable.__Ownable_init(); | ||
transferOwnership(_owner); | ||
conditionStoreManager = ConditionStoreManager( | ||
_conditionStoreManagerAddress | ||
); | ||
|
||
didRegistry = DIDRegistry(_didRegistryAddress); | ||
} | ||
|
||
function hashValues( | ||
bytes32 _did, | ||
address _borrower, | ||
address _collateralAsset, | ||
uint256 _collateralAmount, | ||
address _delegatedAsset, | ||
uint256 _delegatedAmount | ||
) | ||
public | ||
pure | ||
returns (bytes32) { | ||
return | ||
keccak256( | ||
abi.encode( | ||
_did, | ||
_borrower, | ||
_collateralAsset, | ||
_delegatedAsset, | ||
_delegatedAmount, | ||
_collateralAmount | ||
) | ||
); | ||
} | ||
|
||
function fulfill( | ||
bytes32 _agreementId, | ||
bytes32 _did, | ||
address _vaultAddress, | ||
address _borrower, | ||
address _collateralAsset, | ||
address _delegatedAsset, | ||
uint256 _delegatedAmount, | ||
uint256 _collateralAmount | ||
) | ||
external | ||
payable | ||
nonReentrant | ||
returns (ConditionStoreLibrary.ConditionState) { | ||
//Deposits the collateral in the Aave Lending pool contract | ||
|
||
AaveCreditVault vault = AaveCreditVault(_vaultAddress); | ||
|
||
if (msg.value == 0) { | ||
IERC20Upgradeable token = ERC20Upgradeable(_collateralAsset); | ||
token.transferFrom( | ||
msg.sender, | ||
address(vault), | ||
_collateralAmount | ||
); | ||
} | ||
|
||
vault.deposit{value: msg.value}(_collateralAsset, _collateralAmount); | ||
vault.approveBorrower(_borrower, _delegatedAmount, _delegatedAsset); | ||
|
||
bytes32 _id = | ||
generateId( | ||
_agreementId, | ||
hashValues( | ||
_did, | ||
_borrower, | ||
_collateralAsset, | ||
_collateralAmount, | ||
_delegatedAsset, | ||
_delegatedAmount | ||
) | ||
); | ||
|
||
ConditionStoreLibrary.ConditionState state = | ||
super.fulfill(_id, ConditionStoreLibrary.ConditionState.Fulfilled); | ||
|
||
return state; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
pragma solidity 0.6.12; | ||
// Copyright 2020 Keyko GmbH. | ||
// SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) | ||
// Code is Apache-2.0 and docs are CC-BY-4.0 | ||
|
||
|
||
import {IERC20, ILendingPool, IProtocolDataProvider, IStableDebtToken} from '../../../interfaces/IAaveInterfaces.sol'; | ||
import {SafeERC20} from '../../../libraries/AaveLibrary.sol'; | ||
import '../../../interfaces/IWETHGateway.sol'; | ||
import '@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol'; | ||
import '@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol'; | ||
import '@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol'; | ||
|
||
contract AaveCreditVault is ReentrancyGuardUpgradeable, IERC721ReceiverUpgradeable { | ||
|
||
using SafeERC20 for IERC20; | ||
|
||
ILendingPool private lendingPool; | ||
IProtocolDataProvider private dataProvider; | ||
IWETHGateway private weth; | ||
|
||
constructor( | ||
address _lendingPool, | ||
address _dataProvider, | ||
address _weth | ||
) public { | ||
lendingPool = ILendingPool(_lendingPool); | ||
dataProvider = IProtocolDataProvider(_dataProvider); | ||
weth = IWETHGateway(_weth); | ||
} | ||
|
||
function deposit( | ||
address _collateralAsset, | ||
uint256 _amount | ||
) | ||
public | ||
nonReentrant | ||
payable | ||
{ | ||
if (msg.value == 0) _transferERC20(_collateralAsset, _amount); | ||
else { | ||
weth.depositETH{value: msg.value}(address(lendingPool), address(this), 0); | ||
} | ||
} | ||
|
||
function approveBorrower( | ||
address borrower, | ||
uint256 amount, | ||
address asset | ||
) | ||
public | ||
{ | ||
(, address stableDebtTokenAddress, ) = dataProvider | ||
.getReserveTokensAddresses(asset); | ||
IStableDebtToken(stableDebtTokenAddress).approveDelegation( | ||
borrower, | ||
amount | ||
); | ||
} | ||
|
||
/** | ||
* Return the actual delegated amount for the borrower in the specific asset | ||
* @param borrower The borrower of the funds (i.e. delgatee) | ||
* @param asset The asset they are allowed to borrow | ||
*/ | ||
function delegatedAmount( | ||
address borrower, | ||
address asset | ||
) | ||
public | ||
view | ||
returns (uint256) | ||
{ | ||
(, address stableDebtTokenAddress, ) = dataProvider | ||
.getReserveTokensAddresses(asset); | ||
|
||
return | ||
IStableDebtToken(stableDebtTokenAddress).borrowAllowance( | ||
address(this), | ||
borrower | ||
); | ||
} | ||
|
||
/** | ||
* Borrower can call this function to borrow the delegated funds | ||
* @param _assetToBorrow The asset they are allowed to borrow | ||
* @param _amount Amount to borrow | ||
* @param _delgatee Address where the funds will be transfered | ||
*/ | ||
function borrow( | ||
address _assetToBorrow, | ||
uint256 _amount, | ||
address _delgatee | ||
) | ||
public | ||
{ | ||
lendingPool.borrow(_assetToBorrow, _amount, 1, 0, address(this)); | ||
IERC20(_assetToBorrow).transfer(_delgatee, _amount); | ||
} | ||
|
||
/** | ||
* Repay an uncollaterised loan | ||
* @param _amount The amount to repay | ||
* @param _asset The asset to be repaid | ||
*/ | ||
function repay( | ||
uint256 _amount, | ||
address _asset | ||
) | ||
public | ||
{ | ||
IERC20(_asset).approve(address(lendingPool), _amount); | ||
lendingPool.repay(_asset, _amount, 1, address(this)); | ||
} | ||
|
||
/** | ||
* Withdraw all of a collateral as the underlying asset, if no outstanding loans delegated | ||
* @param _asset The underlying asset to withdraw | ||
* @param _delegator Delegator address that deposited the collateral | ||
*/ | ||
function withdrawCollateral( | ||
address _asset, | ||
address _delegator | ||
) | ||
public | ||
{ | ||
(address aTokenAddress, , ) = dataProvider.getReserveTokensAddresses( | ||
_asset | ||
); | ||
uint256 assetBalance = IERC20(aTokenAddress).balanceOf(address(this)); | ||
lendingPool.withdraw(_asset, assetBalance, _delegator); | ||
} | ||
|
||
function _transferERC20( | ||
address _collateralAsset, | ||
uint256 _amount | ||
) | ||
internal | ||
{ | ||
IERC20Upgradeable token = ERC20Upgradeable(_collateralAsset); | ||
token.approve(address(lendingPool), _amount); | ||
lendingPool.deposit(_collateralAsset, _amount, address(this), 0); | ||
} | ||
|
||
/** | ||
* Always returns `IERC721Receiver.onERC721Received.selector`. | ||
*/ | ||
function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) { | ||
return this.onERC721Received.selector; | ||
} | ||
|
||
} |
Oops, something went wrong.