From eee28226847de0532245dc6b6779d0498d3f6fe2 Mon Sep 17 00:00:00 2001 From: Miniroman Date: Tue, 18 Jun 2024 16:10:41 +0200 Subject: [PATCH] Restructure contracts inheritance --- contracts/BackedTokenImplementation.sol | 6 +- ...ntationWithMultiplierAndAutoFeeAccrual.sol | 244 +-------- ...20PermitDelegateTransferWithMultiplier.sol | 87 --- contracts/ERC20UpgradeableWithMultiplier.sol | 4 +- package-lock.json | 496 +----------------- package.json | 2 +- ...entationWithMultiplierAndAutoFeeAccrual.ts | 39 +- 7 files changed, 49 insertions(+), 829 deletions(-) diff --git a/contracts/BackedTokenImplementation.sol b/contracts/BackedTokenImplementation.sol index 28d90ee..c397420 100644 --- a/contracts/BackedTokenImplementation.sol +++ b/contracts/BackedTokenImplementation.sol @@ -97,7 +97,7 @@ contract BackedTokenImplementation is OwnableUpgradeable, ERC20PermitDelegateTra initialize("Backed Token Implementation", "BTI"); } - function initialize(string memory name_, string memory symbol_) public initializer { + function initialize(string memory name_, string memory symbol_) public virtual initializer { __ERC20_init(name_, symbol_); __Ownable_init(); _buildDomainSeparator(); @@ -149,7 +149,7 @@ contract BackedTokenImplementation is OwnableUpgradeable, ERC20PermitDelegateTra uint8 v, bytes32 r, bytes32 s - ) public override allowedDelegate { + ) public virtual override allowedDelegate { super.delegatedTransfer(owner, to, value, deadline, v, r, s); } @@ -172,7 +172,7 @@ contract BackedTokenImplementation is OwnableUpgradeable, ERC20PermitDelegateTra * @param account The account from which the tokens will be burned * @param amount The amount of tokens to be burned */ - function burn(address account, uint256 amount) external { + function burn(address account, uint256 amount) virtual external { require(_msgSender() == burner, "BackedToken: Only burner"); require(account == _msgSender() || account == address(this), "BackedToken: Cannot burn account"); _burn(account, amount); diff --git a/contracts/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.sol b/contracts/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.sol index 733b243..9c987ad 100644 --- a/contracts/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.sol +++ b/contracts/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.sol @@ -36,7 +36,7 @@ pragma solidity 0.8.9; -import "@openzeppelin/contracts-upgradeable-new/access/OwnableUpgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./ERC20PermitDelegateTransferWithMultiplier.sol"; import "./SanctionsList.sol"; @@ -56,30 +56,8 @@ import "./SanctionsList.sol"; * */ -contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is - OwnableUpgradeable, - ERC20PermitDelegateTransferWithMultiplier +contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is ERC20PermitDelegateTransferWithMultiplier { - string public constant VERSION = "1.1.0"; - - // Roles: - address public minter; - address public burner; - address public pauser; - - // EIP-712 Delegate Functionality: - bool public delegateMode; - mapping(address => bool) public delegateWhitelist; - - // Pause: - bool public isPaused; - - // SanctionsList: - SanctionsList public sanctionsList; - - // Terms: - string public terms; - // V2 // Roles: @@ -91,26 +69,7 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is uint256 public periodLength; // Events: - event NewMinter(address indexed newMinter); - event NewBurner(address indexed newBurner); - event NewPauser(address indexed newPauser); event NewMultiplierUpdater(address indexed newMultiplierUpdater); - event NewSanctionsList(address indexed newSanctionsList); - event DelegateWhitelistChange( - address indexed whitelistAddress, - bool status - ); - event DelegateModeChange(bool delegateMode); - event PauseModeChange(bool pauseMode); - event NewTerms(string newTerms); - - modifier allowedDelegate() { - require( - delegateMode || delegateWhitelist[_msgSender()], - "BackedToken: Unauthorized delegate" - ); - _; - } modifier updateMultiplier() { (uint256 newMultiplier, uint256 periodsPassed) = getCurrentMultiplier(); @@ -121,23 +80,16 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is _; } - // constructor, call initializer to lock the implementation instance. - constructor() { - initialize( - "Backed Token Implementation", - "BTI" - ); - } - function initialize( string memory name_, string memory symbol_ - ) public initializer { + ) override public virtual initializer { __ERC20_init(name_, symbol_); - __Multiplier_init(); __Ownable_init(); _buildDomainSeparator(); _setTerms("https://www.backedassets.fi/legal-documentation"); // Default Terms + __Multiplier_init(); + periodLength = 24 * 3600; // Set to 24h by default lastTimeFeeApplied = block.timestamp; } @@ -181,30 +133,6 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is return _totalShares * multiplier / 1e18; } - /** - * @dev Update allowance with a signed permit. Allowed only if - * the sender is whitelisted, or the delegateMode is set to true - * - * @param owner Token owner's address (Authorizer) - * @param spender Spender's address - * @param value Amount of allowance - * @param deadline Expiration time, seconds since the epoch - * @param v v part of the signature - * @param r r part of the signature - * @param s s part of the signature - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public override allowedDelegate { - super.permit(owner, spender, value, deadline, v, r, s); - } - /** * @dev Perform an intended transfer on one account's behalf, from another account, * who actually pays fees for the transaction. Allowed only if the sender @@ -226,7 +154,7 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is uint8 v, bytes32 r, bytes32 s - ) public override allowedDelegate updateMultiplier { + ) public override updateMultiplier { super.delegatedTransfer(owner, to, value, deadline, v, r, s); } @@ -251,7 +179,7 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is uint8 v, bytes32 r, bytes32 s - ) public virtual override updateMultiplier { + ) public virtual override allowedDelegate updateMultiplier { super.delegatedTransferShares(owner, to, value, deadline, v, r, s); } @@ -318,7 +246,7 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is function mint( address account, uint256 amount - ) external virtual updateMultiplier { + ) override external virtual updateMultiplier { require(_msgSender() == minter, "BackedToken: Only minter"); uint256 sharesAmount = getSharesByUnderlyingAmount(amount); _mintShares(account, sharesAmount); @@ -331,7 +259,7 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is * @param account The account from which the tokens will be burned * @param amount The amount of tokens to be burned */ - function burn(address account, uint256 amount) external updateMultiplier { + function burn(address account, uint256 amount) override external virtual updateMultiplier { require(_msgSender() == burner, "BackedToken: Only burner"); require( account == _msgSender() || account == address(this), @@ -350,56 +278,6 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is feePerPeriod = newFeePerPeriod; } - /** - * @dev Function to set the pause in order to block or restore all - * transfers. Allowed only for pauser - * - * Emits a { PauseModeChange } event - * - * @param newPauseMode The new pause mode - */ - function setPause(bool newPauseMode) external { - require(_msgSender() == pauser, "BackedToken: Only pauser"); - isPaused = newPauseMode; - emit PauseModeChange(newPauseMode); - } - - /** - * @dev Function to change the contract minter. Allowed only for owner - * - * Emits a { NewMinter } event - * - * @param newMinter The address of the new minter - */ - function setMinter(address newMinter) external onlyOwner { - minter = newMinter; - emit NewMinter(newMinter); - } - - /** - * @dev Function to change the contract burner. Allowed only for owner - * - * Emits a { NewBurner } event - * - * @param newBurner The address of the new burner - */ - function setBurner(address newBurner) external onlyOwner { - burner = newBurner; - emit NewBurner(newBurner); - } - - /** - * @dev Function to change the contract pauser. Allowed only for owner - * - * Emits a { NewPauser } event - * - * @param newPauser The address of the new pauser - */ - function setPauser(address newPauser) external onlyOwner { - pauser = newPauser; - emit NewPauser(newPauser); - } - /** * @dev Function to change the contract multiplier updater. Allowed only for owner * @@ -434,66 +312,6 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is _updateMultiplier(newMultiplier); } - /** - * @dev Function to change the contract Senctions List. Allowed only for owner - * - * Emits a { NewSanctionsList } event - * - * @param newSanctionsList The address of the new Senctions List following the Chainalysis standard - */ - function setSanctionsList(address newSanctionsList) external onlyOwner { - // Check the proposed sanctions list contract has the right interface: - require( - !SanctionsList(newSanctionsList).isSanctioned(address(this)), - "BackedToken: Wrong List interface" - ); - - sanctionsList = SanctionsList(newSanctionsList); - emit NewSanctionsList(newSanctionsList); - } - - /** - * @dev EIP-712 Function to change the delegate status of account. - * Allowed only for owner - * - * Emits a { DelegateWhitelistChange } event - * - * @param whitelistAddress The address for which to change the delegate status - * @param status The new delegate status - */ - function setDelegateWhitelist( - address whitelistAddress, - bool status - ) external onlyOwner { - delegateWhitelist[whitelistAddress] = status; - emit DelegateWhitelistChange(whitelistAddress, status); - } - - /** - * @dev EIP-712 Function to change the contract delegate mode. Allowed - * only for owner - * - * Emits a { DelegateModeChange } event - * - * @param _delegateMode The new delegate mode for the contract - */ - function setDelegateMode(bool _delegateMode) external onlyOwner { - delegateMode = _delegateMode; - - emit DelegateModeChange(_delegateMode); - } - - /** - * @dev Function to change the contract terms. Allowed only for owner - * - * Emits a { NewTerms } event - * - * @param newTerms A string with the terms. Usually a web or IPFS link. - */ - function setTerms(string memory newTerms) external onlyOwner { - _setTerms(newTerms); - } - /** * @dev Function to change the time of last fee accrual. Allowed only for owner * @@ -512,50 +330,6 @@ contract BackedTokenImplementationWithMultiplierAndAutoFeeAccrual is periodLength = newPeriodLength; } - // Implement setTerms, to allow also to use from initializer: - function _setTerms(string memory newTerms) internal virtual { - terms = newTerms; - emit NewTerms(newTerms); - } - - // Implement the pause and SanctionsList functionality before transfer: - function _beforeTokenTransfer( - address from, - address to, - uint256 amount - ) internal virtual override { - // Check not paused: - require(!isPaused, "BackedToken: token transfer while paused"); - - // Check Sanctions List, but do not prevent minting burning: - if (from != address(0) && to != address(0)) { - require( - !sanctionsList.isSanctioned(from), - "BackedToken: sender is sanctioned" - ); - require( - !sanctionsList.isSanctioned(to), - "BackedToken: receiver is sanctioned" - ); - } - - super._beforeTokenTransfer(from, to, amount); - } - - // Implement the SanctionsList functionality for spender: - function _spendAllowance( - address owner, - address spender, - uint256 amount - ) internal virtual override { - require( - !sanctionsList.isSanctioned(spender), - "BackedToken: spender is sanctioned" - ); - - super._spendAllowance(owner, spender, amount); - } - /** * @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. diff --git a/contracts/ERC20PermitDelegateTransferWithMultiplier.sol b/contracts/ERC20PermitDelegateTransferWithMultiplier.sol index 5d05ce5..cebf83e 100644 --- a/contracts/ERC20PermitDelegateTransferWithMultiplier.sol +++ b/contracts/ERC20PermitDelegateTransferWithMultiplier.sol @@ -24,7 +24,6 @@ pragma solidity 0.8.9; import "./ERC20UpgradeableWithMultiplier.sol"; -import "@openzeppelin/contracts-upgradeable-new/utils/cryptography/ECDSAUpgradeable.sol"; /** * @dev @@ -38,70 +37,11 @@ import "@openzeppelin/contracts-upgradeable-new/utils/cryptography/ECDSAUpgradea */ contract ERC20PermitDelegateTransferWithMultiplier is ERC20UpgradeableWithMultiplier { - mapping(address => uint256) public nonces; - - // Calculating the Permit typehash: - bytes32 public constant PERMIT_TYPEHASH = - keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - - // Calculating the Delegated Transfer typehash: - bytes32 public constant DELEGATED_TRANSFER_TYPEHASH = - keccak256("DELEGATED_TRANSFER(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)"); // Calculating the Delegated Transfer Shares typehash: bytes32 public constant DELEGATED_TRANSFER_SHARES_TYPEHASH = keccak256("DELEGATED_TRANSFER_SHARES(address owner,address to,uint256 value,uint256 nonce,uint256 deadline)"); - // Immutable variable for Domain Separator: - // solhint-disable-next-line var-name-mixedcase - bytes32 public DOMAIN_SEPARATOR; - - // A version number: - // solhint-disable-next-line var-name-mixedcase - string internal constant DOMAIN_SEPARATOR_VERSION = "1"; - - /** - * @dev Permit, approve via a sign message, using erc712. - */ - function permit( - address owner, - address spender, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - - bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); - - _checkOwner(owner, structHash, v, r, s); - - _approve(owner, spender, value); - } - - /** - * @dev Delegated Transfer, transfer via a sign message, using erc712. - */ - function delegatedTransfer( - address owner, - address to, - uint256 value, - uint256 deadline, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual { - require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); - - bytes32 structHash = keccak256(abi.encode(DELEGATED_TRANSFER_TYPEHASH, owner, to, value, _useNonce(owner), deadline)); - - _checkOwner(owner, structHash, v, r, s); - - _transfer(owner, to, value); - } - /** * @dev Delegated Transfer Shares, transfer shares via a sign message, using erc712. */ @@ -122,33 +62,6 @@ contract ERC20PermitDelegateTransferWithMultiplier is ERC20UpgradeableWithMultip _transferShares(owner, to, value); } - /** - * @dev "Consume a nonce": return the current value and increment. - */ - function _useNonce(address owner) internal virtual returns (uint256 current) { - current = nonces[owner]; - nonces[owner]++; - } - - function _checkOwner(address owner, bytes32 structHash, uint8 v, bytes32 r, bytes32 s) internal view { - bytes32 hash = ECDSAUpgradeable.toTypedDataHash(DOMAIN_SEPARATOR, structHash); - - address signer = ECDSAUpgradeable.recover(hash, v, r, s); - require(signer == owner, "ERC20Permit: invalid signature"); - } - - function _buildDomainSeparator() internal { - DOMAIN_SEPARATOR = keccak256( - abi.encode( - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), - keccak256(bytes(name())), - keccak256(bytes(DOMAIN_SEPARATOR_VERSION)), - block.chainid, - address(this) - ) - ); - } - /** * @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. diff --git a/contracts/ERC20UpgradeableWithMultiplier.sol b/contracts/ERC20UpgradeableWithMultiplier.sol index 27af330..d8dd91e 100644 --- a/contracts/ERC20UpgradeableWithMultiplier.sol +++ b/contracts/ERC20UpgradeableWithMultiplier.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; -import "@openzeppelin/contracts-upgradeable-new/token/ERC20/ERC20Upgradeable.sol"; +import "./BackedTokenImplementation.sol"; /** * @dev Implementation of the {IERC20} interface. @@ -30,7 +30,7 @@ import "@openzeppelin/contracts-upgradeable-new/token/ERC20/ERC20Upgradeable.sol * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ -contract ERC20UpgradeableWithMultiplier is ERC20Upgradeable { +contract ERC20UpgradeableWithMultiplier is BackedTokenImplementation { mapping(address => uint256) private _shares; uint256 internal _totalShares; diff --git a/package-lock.json b/package-lock.json index 0163f74..4b204b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "prettier": "^2.5.1", "prettier-plugin-solidity": "^1.0.0-beta.13", "solhint": "^3.3.7", - "solidity-coverage": "^0.8.2", + "solidity-coverage": "^0.8.12", "ts-node": "^10.7.0", "typechain": "^5.2.0", "typescript": "^4.6.2" @@ -2818,15 +2818,6 @@ "node": ">=0.4.0" } }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/adm-zip": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", @@ -4077,20 +4068,6 @@ "node": ">= 0.8" } }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -19695,24 +19672,23 @@ "dev": true }, "node_modules/solidity-coverage": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.2.tgz", - "integrity": "sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ==", + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", + "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.14.1", + "@solidity-parser/parser": "^0.18.0", "chalk": "^2.4.2", "death": "^1.1.0", - "detect-port": "^1.3.0", "difflib": "^0.2.4", "fs-extra": "^8.1.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "7.1.2", + "lodash": "^4.17.21", + "mocha": "^10.2.0", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", @@ -19728,123 +19704,12 @@ "hardhat": "^2.11.0" } }, - "node_modules/solidity-coverage/node_modules/ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/solidity-coverage/node_modules/debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/solidity-coverage/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/solidity-coverage/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", + "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", "dev": true }, - "node_modules/solidity-coverage/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "dependencies": { - "is-buffer": "~2.0.3" - }, - "bin": { - "flat": "cli.js" - } - }, "node_modules/solidity-coverage/node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -19859,38 +19724,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/solidity-coverage/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "deprecated": "\"Please update to latest v2.3 or v2.2\"", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/solidity-coverage/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/solidity-coverage/node_modules/globby": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", @@ -19910,44 +19743,6 @@ "node": ">=8" } }, - "node_modules/solidity-coverage/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/solidity-coverage/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/solidity-coverage/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -19960,148 +19755,6 @@ "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/solidity-coverage/node_modules/mocha": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", - "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", - "dev": true, - "dependencies": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/solidity-coverage/node_modules/ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/solidity-coverage/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/solidity-coverage/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/solidity-coverage/node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/solidity-coverage/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -20117,139 +19770,12 @@ "node": ">=10" } }, - "node_modules/solidity-coverage/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/solidity-coverage/node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, - "node_modules/solidity-coverage/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/solidity-coverage/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, "node_modules/solidity-coverage/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/solidity-coverage/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/solidity-coverage/node_modules/yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "dependencies": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", diff --git a/package.json b/package.json index 75320c9..648e202 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "prettier": "^2.5.1", "prettier-plugin-solidity": "^1.0.0-beta.13", "solhint": "^3.3.7", - "solidity-coverage": "^0.8.2", + "solidity-coverage": "^0.8.12", "ts-node": "^10.7.0", "typechain": "^5.2.0", "typescript": "^4.6.2" diff --git a/test/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.ts b/test/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.ts index 26fc41f..e33d002 100644 --- a/test/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.ts +++ b/test/BackedTokenImplementationWithMultiplierAndAutoFeeAccrual.ts @@ -24,7 +24,7 @@ type SignerWithAddress = { // BackedTokenImplementationWithMultiplierAndAutoFeeAccrual specifications // Vast majority of comparisons are done with adjustment for precision of calculations, thus we are rather comparing difference of values, // rather than values themselves -describe.only("BackedTokenImplementationWithMultiplierAndAutoFeeAccrual", function () { +describe("BackedTokenImplementationWithMultiplierAndAutoFeeAccrual", function () { const accrualPeriodLength = 24 * 3600; const annualFee = 0.5; const multiplierAdjustmentPerPeriod = nthRoot(annualFee, 365).mul(Decimal.pow(10, 18)); @@ -239,15 +239,6 @@ describe.only("BackedTokenImplementationWithMultiplierAndAutoFeeAccrual", functi it('Should allow transfer of current balance of user', async () => { await expect(token.transfer(actor.address, (await token.balanceOf(actor.address)))).to.not.be.reverted; }) - it('Should allow transfer of current balance of user', async () => { - await expect(token.transfer(actor.address, (await token.balanceOf(actor.address)).div(2))).to.not.be.reverted; - await expect(token.transfer(actor.address, (await token.balanceOf(actor.address)))).to.not.be.reverted; - }) - it('Should allow transfer of current balance of user', async () => { - await token.updateFeePerPeriod(0); - await expect(token.transfer(actor.address, (await token.balanceOf(actor.address)).div(2))).to.not.be.reverted; - await expect(token.transfer(actor.address, (await token.balanceOf(actor.address)))).to.not.be.reverted; - }) }); describe('#transferShares', () => { it('Should allow transfer of shares of user', async () => { @@ -351,13 +342,29 @@ describe.only("BackedTokenImplementationWithMultiplierAndAutoFeeAccrual", functi const signer = await ethers.getSigner(owner.address); signature = await signer._signTypedData(domain, types, msg); }) - it('Should move requested shares of tokens', async () => { - await subject(); - expect((await token.sharesOf(actor.address))).to.be.eq(sharesToTransfer); + describe('And caller is whitelisted delegate', () => { + cacheBeforeEach(async () => { + await token.setDelegateWhitelist(actor.address, true); + }) + it('Should move requested shares of tokens', async () => { + await subject(); + expect((await token.sharesOf(actor.address))).to.be.eq(sharesToTransfer); + }) + it('Should increase balance of destination wallet', async () => { + await subject(); + expect((await token.balanceOf(actor.address))).to.be.eq(userBalance); + }) + it('Should revert if deadline already passed', async () => { + await helpers.time.setNextBlockTimestamp(deadline + 1); + await helpers.mine() + await expect(subject()).to.be.reverted; + }) }) - it('Should increase balance of destination wallet', async () => { - await subject(); - expect((await token.balanceOf(actor.address))).to.be.eq(userBalance); + describe('And caller is whitelisted delegate', () => { + + it('Should revert', async () => { + await expect(subject()).to.be.reverted; + }) }) }) });