diff --git a/modules/allowances/CHANGELOG.md b/modules/allowances/CHANGELOG.md new file mode 100644 index 00000000..455ff9df --- /dev/null +++ b/modules/allowances/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog + +This changelog only contains changes starting from version 0.1.1 + +# Version 0.1.1 + +## Compiler settings + +Solidity compiler: [0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6) + +Solidity optimizer: disabled + +## Expected addresses + +- `AllowanceModule` at `0xAA46724893dedD72658219405185Fb0Fc91e091C` + +## Changes + +### General + +#### Fix the EIP-712 transfer typehash + +Issue: [#70](https://github.com/safe-global/safe-modules/issues/70) + +The typehash for the transfer was incorrect, making it impossible to use the module with EIP-712 signatures. + +#### Add a check for `resetTimeMin` + +For recurring allowances, the `resetTimeMin` must be greater than 0. However, the check was missing, making it possible to specify a `resetTimeMin` of 0, resulting in a divide by zero error and the transaction consuming all gas. + +The change was suggested by the [Ackee blockchain](https://ackee.xyz/) during the audit of the module. \ No newline at end of file diff --git a/modules/allowances/README.md b/modules/allowances/README.md index 74f7342a..1eccbbc0 100644 --- a/modules/allowances/README.md +++ b/modules/allowances/README.md @@ -122,4 +122,26 @@ pnpm test ```bash pnpm i pnpm build -``` \ No newline at end of file +``` + +## Deploying and verifying contracts + +Specify all the necessary environment variables in `.env`, following the `.env.sample` file. + +```bash +pnpm i +pnpm run deploy +``` + +1. `network_name` is the name of the network you want to deploy to. It must be added to the hardhat config under `networks` beforehand. +2. If the hardhat plugin cannot figure out the etherscan API url for the network, you can add it manually to `tasks/deploy_verify.ts`. +Example: +```ts +await hre.run('etherscan-verify', { + forceLicense: true, + license: 'LGPL-3.0', + apiUrl: "https://api.gnosiscan.io" +}) +``` + + diff --git a/modules/allowances/contracts/AllowanceModule.sol b/modules/allowances/contracts/AllowanceModule.sol index 8a3525a5..5e1d35f4 100644 --- a/modules/allowances/contracts/AllowanceModule.sol +++ b/modules/allowances/contracts/AllowanceModule.sol @@ -20,7 +20,7 @@ interface ISafe { contract AllowanceModule is SignatureDecoder { string public constant NAME = "Allowance Module"; - string public constant VERSION = "0.1.0"; + string public constant VERSION = "0.1.1"; bytes32 public constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218; // keccak256( @@ -89,7 +89,7 @@ contract AllowanceModule is SignatureDecoder { // solium-disable-next-line security/no-block-members uint32 currentMin = uint32(block.timestamp / 60); if (resetBaseMin > 0) { - require(resetBaseMin <= currentMin, "resetBaseMin <= currentMin"); + require(resetBaseMin <= currentMin && resetTimeMin > 0, "resetBaseMin <= currentMin && resetTimeMin > 0"); allowance.lastResetMin = currentMin - ((currentMin - resetBaseMin) % resetTimeMin); } else if (allowance.lastResetMin == 0) { allowance.lastResetMin = currentMin; diff --git a/modules/allowances/docs/ackee-blockchain-safe-allowance-module-report.pdf b/modules/allowances/docs/ackee-blockchain-safe-allowance-module-report.pdf new file mode 100644 index 00000000..f723a5a5 Binary files /dev/null and b/modules/allowances/docs/ackee-blockchain-safe-allowance-module-report.pdf differ diff --git a/modules/allowances/hardhat.config.ts b/modules/allowances/hardhat.config.ts index f19877f3..66fab4dd 100644 --- a/modules/allowances/hardhat.config.ts +++ b/modules/allowances/hardhat.config.ts @@ -58,26 +58,10 @@ const config: HardhatUserConfig = { ...sharedNetworkConfig, url: 'https://rpc.gnosischain.com', }, - ewc: { - ...sharedNetworkConfig, - url: `https://rpc.energyweb.org`, - }, - goerli: { - ...sharedNetworkConfig, - url: `https://goerli.infura.io/v3/${INFURA_KEY}`, - }, - mumbai: { - ...sharedNetworkConfig, - url: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`, - }, polygon: { ...sharedNetworkConfig, url: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`, }, - volta: { - ...sharedNetworkConfig, - url: `https://volta-rpc.energyweb.org`, - }, bsc: { ...sharedNetworkConfig, url: `https://bsc-dataseed.binance.org/`, diff --git a/modules/allowances/package.json b/modules/allowances/package.json index c82cd1e0..c71d8bfa 100644 --- a/modules/allowances/package.json +++ b/modules/allowances/package.json @@ -1,6 +1,6 @@ { "name": "@safe-global/safe-allowance-module", - "version": "1.0.0", + "version": "0.1.1", "description": "Allowance module for the gnosis safe", "keywords": [ "Ethereum", diff --git a/modules/allowances/test/allowanceRecurring.spec.ts b/modules/allowances/test/allowanceRecurring.spec.ts index 3006766d..63a0be1e 100644 --- a/modules/allowances/test/allowanceRecurring.spec.ts +++ b/modules/allowances/test/allowanceRecurring.spec.ts @@ -133,4 +133,24 @@ describe('AllowanceModule allowanceRecurring', () => { expect(expectedLastReset).to.be.equal(resetLast) expect(4).to.equal(nonce) }) + + it('Reverts when trying to set up a recurring allowance with reset period of 0', async () => { + const { safe, allowanceModule, token, owner, alice } = await loadFixture(setup) + const tokenAddress = await token.getAddress() + + // add alice as delegate + await execSafeTransaction(safe, await allowanceModule.addDelegate.populateTransaction(alice.address), owner) + + // create an allowance for alice + const configResetPeriod = 0 + const configResetBase = nowInMinutes() + + await expect( + execSafeTransaction( + safe, + await allowanceModule.setAllowance.populateTransaction(alice.address, tokenAddress, 100, configResetPeriod, configResetBase), + owner, + ), + ).to.be.reverted + }) })