From e6809c35f73b7d85015e8986a5a05f61411459a9 Mon Sep 17 00:00:00 2001 From: Seth Date: Mon, 2 Oct 2023 00:23:20 +0800 Subject: [PATCH 1/2] fix: retrieve decimals from asset --- contracts/TimeLockVault.sol | 13 +++++++ contracts/interfaces/TimeLockVaultErrors.sol | 2 ++ contracts/mocks/MockTimeLockVault.sol | 4 +++ .../time-lock-vault-setup.spec.ts | 34 +++++++++++++++++-- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/contracts/TimeLockVault.sol b/contracts/TimeLockVault.sol index 599548a..4c453ea 100644 --- a/contracts/TimeLockVault.sol +++ b/contracts/TimeLockVault.sol @@ -99,6 +99,19 @@ abstract contract TimeLockVault is ERC20Upgradeable, ITimeLockVault, TimeLockVau return _asset.balanceOf(address(this)); } + function decimals() + public + view + virtual + override(ERC20Upgradeable, IERC20MetadataUpgradeable) + returns (uint8) + { + if (address(_asset) == address(0)) { + revert AssetUndefined(); + } + return _asset.decimals(); + } + function _setAsset(address asset_) internal { _asset = IERC20MetadataUpgradeable(asset_); } diff --git a/contracts/interfaces/TimeLockVaultErrors.sol b/contracts/interfaces/TimeLockVaultErrors.sol index bd14092..de69a78 100644 --- a/contracts/interfaces/TimeLockVaultErrors.sol +++ b/contracts/interfaces/TimeLockVaultErrors.sol @@ -6,6 +6,8 @@ interface TimeLockVaultErrors { error InvalidActiveDeposit(); + error AssetUndefined(); + error DepositNotMatured(); error DepositAlreadyMatured(); diff --git a/contracts/mocks/MockTimeLockVault.sol b/contracts/mocks/MockTimeLockVault.sol index dfa4178..79143a6 100644 --- a/contracts/mocks/MockTimeLockVault.sol +++ b/contracts/mocks/MockTimeLockVault.sol @@ -18,4 +18,8 @@ contract MockTimeLockVault is SimpleTimeLockVault { ) public returns (DepositInfo memory) { return _prematureWithdraw(from, to, depositId); } + + function setAssetInternal(address asset_) public { + _setAsset(asset_); + } } diff --git a/test/TimeLockVault/time-lock-vault-setup.spec.ts b/test/TimeLockVault/time-lock-vault-setup.spec.ts index c983d0f..fac60eb 100644 --- a/test/TimeLockVault/time-lock-vault-setup.spec.ts +++ b/test/TimeLockVault/time-lock-vault-setup.spec.ts @@ -1,5 +1,6 @@ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; import { expect } from "chai"; +import { constants } from "ethers"; import { MockTimeLockVault } from "../../types"; import { deployMockTimeLockVaultFixture } from "./time-lock-vault.fixture"; @@ -15,10 +16,37 @@ describe("Time-Lock Vault", () => { }); describe("Setup", () => { - it("should return the correct asset contract address", async () => { - const asset = await mockVaultContract.asset(); + describe("When asset is specified", () => { + it("should return the correct asset contract address", async () => { + const asset = await mockVaultContract.asset(); - expect(asset).to.equal(fixtures.mockERC20Contract.address); + expect(asset).to.equal(fixtures.mockERC20Contract.address); + }); + + it("should have the same decimals as asset contract", async () => { + const decimals = await mockVaultContract.decimals(); + const assetDecimals = await fixtures.mockERC20Contract.decimals(); + + expect(decimals).to.equal(assetDecimals); + }); + }); + + describe("When asset is zero address", () => { + beforeEach(async () => { + await mockVaultContract + .connect(fixtures.signers.deployer) + .setAssetInternal(constants.AddressZero); + + // Assert that asset is zero address + const asset = await mockVaultContract.asset(); + expect(asset).to.equal(constants.AddressZero); + }); + + it("should revert when returning decimals", async () => { + const tx = mockVaultContract.decimals(); + + await expect(tx).to.be.revertedWithCustomError(mockVaultContract, "AssetUndefined"); + }); }); }); }); From 2adc9223e9403ba9d1538df966d65dbf78e47424 Mon Sep 17 00:00:00 2001 From: Seth Date: Mon, 2 Oct 2023 00:26:18 +0800 Subject: [PATCH 2/2] chore: bump oz version --- package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index edf00b6..537005c 100644 --- a/package.json +++ b/package.json @@ -55,8 +55,8 @@ "typescript": "^4.9.5" }, "dependencies": { - "@openzeppelin/contracts": "^4.8.3", - "@openzeppelin/contracts-upgradeable": "^4.8.3" + "@openzeppelin/contracts": "^4.9.3", + "@openzeppelin/contracts-upgradeable": "^4.9.3" }, "files": [ "/contracts" diff --git a/yarn.lock b/yarn.lock index c8abcb9..9d3b340 100644 --- a/yarn.lock +++ b/yarn.lock @@ -901,15 +901,15 @@ table "^6.8.0" undici "^5.14.0" -"@openzeppelin/contracts-upgradeable@^4.8.3": - version "4.8.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.3.tgz#6b076a7b751811b90fe3a172a7faeaa603e13a3f" - integrity sha512-SXDRl7HKpl2WDoJpn7CK/M9U4Z8gNXDHHChAKh0Iz+Wew3wu6CmFYBeie3je8V0GSXZAIYYwUktSrnW/kwVPtg== - -"@openzeppelin/contracts@^4.8.3": - version "4.8.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.3.tgz#cbef3146bfc570849405f59cba18235da95a252a" - integrity sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg== +"@openzeppelin/contracts-upgradeable@^4.9.3": + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" + integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== + +"@openzeppelin/contracts@^4.9.3": + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" + integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== "@scure/base@~1.1.0": version "1.1.1"