From 43c8ef02dbcfae1fbbbde572345ecd54637108d1 Mon Sep 17 00:00:00 2001 From: andyk Date: Tue, 15 Sep 2020 16:53:20 +0300 Subject: [PATCH] initial integration of pei, no tests --- .../interfaces/IAaveIncentivesController.sol | 11 +++++ contracts/mocks/upgradeability/MockAToken.sol | 5 ++- .../upgradeability/MockStableDebtToken.sol | 8 +++- .../upgradeability/MockVariableDebtToken.sol | 14 ++++++- contracts/tokenization/AToken.sol | 20 ++++++++- contracts/tokenization/ERC20.sol | 41 ++++++++++++++++--- contracts/tokenization/StableDebtToken.sol | 5 ++- contracts/tokenization/VariableDebtToken.sol | 5 ++- contracts/tokenization/base/DebtTokenBase.sol | 5 ++- contracts/tokenization/interfaces/IAToken.sol | 8 ++++ 10 files changed, 102 insertions(+), 20 deletions(-) create mode 100644 contracts/interfaces/IAaveIncentivesController.sol diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol new file mode 100644 index 00000000..83f1769c --- /dev/null +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.8; +pragma experimental ABIEncoderV2; + +interface IAaveIncentivesController { + function handleAction( + address user, + uint256 userBalance, + uint256 totalSupply + ) external; +} diff --git a/contracts/mocks/upgradeability/MockAToken.sol b/contracts/mocks/upgradeability/MockAToken.sol index 05f0db4e..f84543d9 100644 --- a/contracts/mocks/upgradeability/MockAToken.sol +++ b/contracts/mocks/upgradeability/MockAToken.sol @@ -9,8 +9,9 @@ contract MockAToken is AToken { LendingPool _pool, address _underlyingAssetAddress, string memory _tokenName, - string memory _tokenSymbol - ) public AToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {} + string memory _tokenSymbol, + address incentivesController + ) public AToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol, incentivesController) {} function getRevision() internal override pure returns (uint256) { return 0x2; diff --git a/contracts/mocks/upgradeability/MockStableDebtToken.sol b/contracts/mocks/upgradeability/MockStableDebtToken.sol index 52e7a99f..6f44cf07 100644 --- a/contracts/mocks/upgradeability/MockStableDebtToken.sol +++ b/contracts/mocks/upgradeability/MockStableDebtToken.sol @@ -9,8 +9,12 @@ contract MockStableDebtToken is StableDebtToken { address _pool, address _underlyingAssetAddress, string memory _tokenName, - string memory _tokenSymbol - ) public StableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {} + string memory _tokenSymbol, + address incentivesController + ) + public + StableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol, incentivesController) + {} function getRevision() internal override pure returns (uint256) { return 0x2; diff --git a/contracts/mocks/upgradeability/MockVariableDebtToken.sol b/contracts/mocks/upgradeability/MockVariableDebtToken.sol index cb46d4d8..4e4a7ffa 100644 --- a/contracts/mocks/upgradeability/MockVariableDebtToken.sol +++ b/contracts/mocks/upgradeability/MockVariableDebtToken.sol @@ -9,8 +9,18 @@ contract MockVariableDebtToken is VariableDebtToken { address _pool, address _underlyingAssetAddress, string memory _tokenName, - string memory _tokenSymbol - ) public VariableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {} + string memory _tokenSymbol, + address incentivesController + ) + public + VariableDebtToken( + _pool, + _underlyingAssetAddress, + _tokenName, + _tokenSymbol, + incentivesController + ) + {} function getRevision() internal override pure returns (uint256) { return 0x2; diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index c2924d3d..3c248fdb 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -45,8 +45,9 @@ contract AToken is VersionedInitializable, ERC20, IAToken { LendingPool pool, address underlyingAssetAddress, string memory tokenName, - string memory tokenSymbol - ) public ERC20(tokenName, tokenSymbol, 18) { + string memory tokenSymbol, + address incentivesController + ) public ERC20(tokenName, tokenSymbol, 18, incentivesController) { POOL = pool; UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress; } @@ -161,6 +162,21 @@ contract AToken is VersionedInitializable, ERC20, IAToken { return super.balanceOf(user); } + /** + * @dev returns the principal balance of the user and principal total supply. + * @param user the address of the user + * @return the principal balance of the user + * @return the principal total supply + **/ + function getScaledUserBalanceAndSupply(address user) + external + override + view + returns (uint256, uint256) + { + return (super.balanceOf(user), super.totalSupply()); + } + /** * @dev calculates the total supply of the specific aToken * since the balance of every single user increases over time, the total supply diff --git a/contracts/tokenization/ERC20.sol b/contracts/tokenization/ERC20.sol index f2902ce4..91194087 100644 --- a/contracts/tokenization/ERC20.sol +++ b/contracts/tokenization/ERC20.sol @@ -5,6 +5,7 @@ import {Context} from '../misc/Context.sol'; import {IERC20} from '../interfaces/IERC20.sol'; import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol'; import {SafeMath} from '../libraries/math/SafeMath.sol'; +import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol'; /** * @title ERC20 @@ -14,6 +15,8 @@ import {SafeMath} from '../libraries/math/SafeMath.sol'; contract ERC20 is Context, IERC20, IERC20Detailed { using SafeMath for uint256; + IAaveIncentivesController internal immutable _incentivesController; + mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; @@ -24,11 +27,13 @@ contract ERC20 is Context, IERC20, IERC20Detailed { constructor( string memory name, string memory symbol, - uint8 decimals + uint8 decimals, + address incentivesController ) public { _name = name; _symbol = symbol; _decimals = decimals; + _incentivesController = IAaveIncentivesController(incentivesController); } /** @@ -167,8 +172,16 @@ contract ERC20 is Context, IERC20, IERC20Detailed { _beforeTokenTransfer(sender, recipient, amount); - _balances[sender] = _balances[sender].sub(amount, 'ERC20: transfer amount exceeds balance'); + uint256 oldSenderBalance = _balances[sender]; + _balances[sender] = oldSenderBalance.sub(amount, 'ERC20: transfer amount exceeds balance'); + uint256 oldRecipientBalance = _balances[recipient]; _balances[recipient] = _balances[recipient].add(amount); + + if (address(_incentivesController) != address(0x0)) { + uint256 totalSupply = _totalSupply; + _incentivesController.handleAction(sender, totalSupply, oldSenderBalance); + _incentivesController.handleAction(recipient, totalSupply, oldRecipientBalance); + } emit Transfer(sender, recipient, amount); } @@ -177,8 +190,16 @@ contract ERC20 is Context, IERC20, IERC20Detailed { _beforeTokenTransfer(address(0), account, amount); - _totalSupply = _totalSupply.add(amount); - _balances[account] = _balances[account].add(amount); + uint256 oldTotalSupply = _totalSupply; + _totalSupply = oldTotalSupply.add(amount); + + uint256 oldAccountBalance = _balances[account]; + _balances[account] = oldAccountBalance.add(amount); + + if (address(_incentivesController) != address(0x0)) { + _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); + } + emit Transfer(address(0), account, amount); } @@ -187,8 +208,16 @@ contract ERC20 is Context, IERC20, IERC20Detailed { _beforeTokenTransfer(account, address(0), amount); - _balances[account] = _balances[account].sub(amount, 'ERC20: burn amount exceeds balance'); - _totalSupply = _totalSupply.sub(amount); + uint256 oldTotalSupply = _totalSupply; + _totalSupply = oldTotalSupply.sub(amount); + + uint256 oldAccountBalance = _balances[account]; + _balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance'); + + if (address(_incentivesController) != address(0x0)) { + _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); + } + emit Transfer(account, address(0), amount); } diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 8e5da21b..fd2affca 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -26,8 +26,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { address pool, address underlyingAsset, string memory name, - string memory symbol - ) public DebtTokenBase(pool, underlyingAsset, name, symbol) {} + string memory symbol, + address incentivesController + ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {} /** * @dev gets the revision of the stable debt token implementation diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index e52f7c61..879ffc17 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -22,8 +22,9 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { address pool, address underlyingAsset, string memory name, - string memory symbol - ) public DebtTokenBase(pool, underlyingAsset, name, symbol) {} + string memory symbol, + address incentivesController + ) public DebtTokenBase(pool, underlyingAsset, name, symbol, incentivesController) {} /** * @dev gets the revision of the stable debt token implementation diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index a6bd4005..f09e92d4 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -38,8 +38,9 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable { address pool, address underlyingAssetAddress, string memory name, - string memory symbol - ) public ERC20(name, symbol, 18) { + string memory symbol, + address incentivesController + ) public ERC20(name, symbol, 18, incentivesController) { POOL = ILendingPool(pool); UNDERLYING_ASSET = underlyingAssetAddress; } diff --git a/contracts/tokenization/interfaces/IAToken.sol b/contracts/tokenization/interfaces/IAToken.sol index 873860a9..e1975074 100644 --- a/contracts/tokenization/interfaces/IAToken.sol +++ b/contracts/tokenization/interfaces/IAToken.sol @@ -82,6 +82,14 @@ interface IAToken is IERC20 { **/ function scaledBalanceOf(address user) external view returns (uint256); + /** + * @dev returns the principal balance of the user and principal total supply. + * @param user the address of the user + * @return the principal balance of the user + * @return the principal total supply + **/ + function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); + /** * @dev Used to validate transfers before actually executing them. * @param user address of the user to check