diff --git a/contracts/ERC20UpgradeableWithMultiplier.sol b/contracts/ERC20UpgradeableWithMultiplier.sol index 33413eb..9488252 100644 --- a/contracts/ERC20UpgradeableWithMultiplier.sol +++ b/contracts/ERC20UpgradeableWithMultiplier.sol @@ -3,10 +3,7 @@ pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; /** * @dev Implementation of the {IERC20} interface. @@ -33,16 +30,11 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ -contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { +contract ERC20UpgradeableWithMultiplier is ERC20Upgradeable { mapping(address => uint256) private _shares; - mapping(address => mapping(address => uint256)) private _allowances; - uint256 internal _totalShares; - string private _name; - string private _symbol; - /** * @dev Defines ratio between a single share of a token to balance of a token. * Defined in 1e18 precision. @@ -72,48 +64,14 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE * All two of these values are immutable: they can only be set once during * construction. */ - function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { - __ERC20_init_unchained(name_, symbol_); + function __Multiplier_init() internal onlyInitializing { + __Multiplier_init_unchained(); } - function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { - _name = name_; - _symbol = symbol_; + function __Multiplier_init_unchained() internal onlyInitializing { _multiplier = 1e18; } - - /** - * @dev Returns the name of the token. - */ - function name() public view virtual override returns (string memory) { - return _name; - } - - /** - * @dev Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public view virtual override returns (string memory) { - return _symbol; - } - - /** - * @dev Returns the number of decimals used to get its user representation. - * For example, if `decimals` equals `2`, a balance of `505` tokens should - * be displayed to a user as `5.05` (`505 / 10 ** 2`). - * - * Tokens usually opt for a value of 18, imitating the relationship between - * Ether and Wei. This is the value {ERC20} uses, unless this function is - * overridden; - * - * NOTE: This information is only used for _display_ purposes: it in - * no way affects any of the arithmetic of the contract, including - * {IERC20-balanceOf} and {IERC20-transfer}. - */ - function decimals() public view virtual override returns (uint8) { - return 18; - } - + /** * @dev See {IERC20-totalSupply}. */ @@ -142,20 +100,6 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE return _shares[account]; } - /** - * @dev See {IERC20-transfer}. - * - * Requirements: - * - * - `to` cannot be the zero address. - * - the caller must have a balance of at least `amount`. - */ - function transfer(address to, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _transfer(owner, to, amount); - return true; - } - /** * @dev Transfers underlying shares to destination account * @@ -170,99 +114,6 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE return true; } - /** - * @dev See {IERC20-allowance}. - */ - function allowance(address owner, address spender) public view virtual override returns (uint256) { - return _allowances[owner][spender]; - } - - /** - * @dev See {IERC20-approve}. - * - * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on - * `transferFrom`. This is semantically equivalent to an infinite approval. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function approve(address spender, uint256 amount) public virtual override returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, amount); - return true; - } - - /** - * @dev See {IERC20-transferFrom}. - * - * Emits an {Approval} event indicating the updated allowance. This is not - * required by the EIP. See the note at the beginning of {ERC20}. - * - * NOTE: Does not update the allowance if the current allowance - * is the maximum `uint256`. - * - * Requirements: - * - * - `from` and `to` cannot be the zero address. - * - `from` must have a balance of at least `amount`. - * - the caller must have allowance for ``from``'s tokens of at least - * `amount`. - */ - function transferFrom( - address from, - address to, - uint256 amount - ) public virtual override returns (bool) { - address spender = _msgSender(); - _spendAllowance(from, spender, amount); - _transfer(from, to, amount); - return true; - } - - /** - * @dev Atomically increases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - */ - function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { - address owner = _msgSender(); - _approve(owner, spender, _allowances[owner][spender] + addedValue); - return true; - } - - /** - * @dev Atomically decreases the allowance granted to `spender` by the caller. - * - * This is an alternative to {approve} that can be used as a mitigation for - * problems described in {IERC20-approve}. - * - * Emits an {Approval} event indicating the updated allowance. - * - * Requirements: - * - * - `spender` cannot be the zero address. - * - `spender` must have allowance for the caller of at least - * `subtractedValue`. - */ - function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { - address owner = _msgSender(); - uint256 currentAllowance = _allowances[owner][spender]; - require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); - unchecked { - _approve(owner, spender, currentAllowance - subtractedValue); - } - - return true; - } - /** * @return the amount of shares that corresponds to `_underlyingAmount` underlying amount. */ @@ -329,7 +180,7 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE address from, address to, uint256 amount - ) internal virtual { + ) internal virtual override { uint256 _sharesToTransfer = getSharesByUnderlyingAmount(amount); _transferShares(from, to, _sharesToTransfer); } @@ -389,53 +240,6 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE _afterTokenTransfer(account, address(0), amount); } - /** - * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. - * - * This internal function is equivalent to `approve`, and can be used to - * e.g. set automatic allowances for certain subsystems, etc. - * - * Emits an {Approval} event. - * - * Requirements: - * - * - `owner` cannot be the zero address. - * - `spender` cannot be the zero address. - */ - function _approve( - address owner, - address spender, - uint256 amount - ) internal virtual { - require(owner != address(0), "ERC20: approve from the zero address"); - require(spender != address(0), "ERC20: approve to the zero address"); - - _allowances[owner][spender] = amount; - emit Approval(owner, spender, amount); - } - - /** - * @dev Spend `amount` form the allowance of `owner` toward `spender`. - * - * Does not update the allowance amount in case of infinite allowance. - * Revert if not enough allowance is available. - * - * Might emit an {Approval} event. - */ - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual { - uint256 currentAllowance = allowance(owner, spender); - if (currentAllowance != type(uint256).max) { - require(currentAllowance >= amount, "ERC20: insufficient allowance"); - unchecked { - _approve(owner, spender, currentAllowance - amount); - } - } - } - /** * @dev Updates currently stored multiplier with a new value * @@ -448,50 +252,10 @@ contract ERC20UpgradeableWithMultiplier is Initializable, ContextUpgradeable, IE emit MultiplierUpdated(newMultiplier); } - /** - * @dev Hook that is called before any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * will be transferred to `to`. - * - when `from` is zero, `amount` tokens will be minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens will be burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} - - /** - * @dev Hook that is called after any transfer of tokens. This includes - * minting and burning. - * - * Calling conditions: - * - * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens - * has been transferred to `to`. - * - when `from` is zero, `amount` tokens have been minted for `to`. - * - when `to` is zero, `amount` of ``from``'s tokens have been burned. - * - `from` and `to` are never both zero. - * - * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. - */ - function _afterTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual {} - /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[44] private __gap; + uint256[47] private __gap; } diff --git a/package-lock.json b/package-lock.json index 33e9561..40be30e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "chai": "^4.3.6", + "decimal.js": "^10.4.3", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", @@ -4004,6 +4005,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "node_modules/deep-eql": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",