Skip to content

Commit

Permalink
Merge pull request #65 from hats-finance/fix-54
Browse files Browse the repository at this point in the history
Fix #54
  • Loading branch information
jellegerbrandy authored Dec 4, 2023
2 parents fc0c464 + 933528f commit 19117c0
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
17 changes: 14 additions & 3 deletions contracts/tokenlock/TokenLock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ abstract contract TokenLock is Ownable, ITokenLock {
error AmountCannotBeZero();
error AmountRequestedBiggerThanSurplus();
error LockIsNonRevocable();
error LockIsAlreadyRevoked();
error NoAvailableUnvestedAmount();
error OnlySweeper();
error CannotSweepVestedToken();
Expand Down Expand Up @@ -190,17 +191,27 @@ abstract contract TokenLock is Ownable, ITokenLock {
if (!revocable)
revert LockIsNonRevocable();

uint256 unvestedAmount = managedAmount - vestedAmount();
if (isRevoked)
revert LockIsAlreadyRevoked();

uint256 vestedAmount = vestedAmount();

uint256 unvestedAmount = managedAmount - vestedAmount;
if (unvestedAmount == 0)
revert NoAvailableUnvestedAmount();

isRevoked = true;

managedAmount = vestedAmount;

// solhint-disable-next-line not-rely-on-time
endTime = block.timestamp;

token.safeTransfer(owner(), unvestedAmount);

emit TokensRevoked(beneficiary, unvestedAmount);

selfdestruct(payable(msg.sender));
trySelfDestruct();
}

/**
Expand Down Expand Up @@ -445,7 +456,7 @@ abstract contract TokenLock is Ownable, ITokenLock {
}

function trySelfDestruct() private {
if (currentTime() > endTime && currentBalance() == 0) {
if (currentTime() >= endTime && currentBalance() == 0) {
selfdestruct(payable(msg.sender));
}
}
Expand Down
11 changes: 11 additions & 0 deletions docs/dodoc/tokenlock/HATTokenLock.md
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,17 @@ error DelegateDisabled()



### LockIsAlreadyRevoked

```solidity
error LockIsAlreadyRevoked()
```






### LockIsNonRevocable

```solidity
Expand Down
11 changes: 11 additions & 0 deletions docs/dodoc/tokenlock/TokenLock.md
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,17 @@ error CliffTimeMustBeBeforeEndTime()



### LockIsAlreadyRevoked

```solidity
error LockIsAlreadyRevoked()
```






### LockIsNonRevocable

```solidity
Expand Down
28 changes: 28 additions & 0 deletions test/tokenlock.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,18 @@ contract("TokenLock", (accounts) => {
}
});

it("cannot revoke twice", async () => {
await setup(accounts);
await utils.increaseTime(300);
await tokenLock.revoke();
try {
await tokenLock.revoke();
assert(false, "cannot revoke after lock was already revoked");
} catch (ex) {
assertVMException(ex, "LockIsAlreadyRevoked");
}
});

it("sinceStartTime", async () => {
await setup(accounts, true, false, 100);
assert.equal(await tokenLock.sinceStartTime(), 0);
Expand All @@ -305,6 +317,22 @@ contract("TokenLock", (accounts) => {
assert.equal(await tokenLock.availableAmount(), web3.utils.toWei("0.2"));
});

it("redeem and withdraw surplus after revoke", async () => {
await setup(accounts);
await stakingToken.mint(tokenLock.address, web3.utils.toWei("1"));
await utils.increaseTime(300);
await tokenLock.revoke();
assert.equal(await stakingToken.balanceOf(accounts[0]), web3.utils.toWei("0.8"));
assert.equal(await stakingToken.balanceOf(tokenLock.address), web3.utils.toWei("1.2"));
await tokenLock.release({ from: accounts[1] });
assert.equal(await stakingToken.balanceOf(accounts[1]), web3.utils.toWei("0.2"));
assert.equal(await stakingToken.balanceOf(tokenLock.address), web3.utils.toWei("1"));
await tokenLock.withdrawSurplus(web3.utils.toWei("1"), { from: accounts[1] });
assert.equal(await stakingToken.balanceOf(accounts[1]), web3.utils.toWei("1.2"));
assert.equal(await stakingToken.balanceOf(tokenLock.address), web3.utils.toWei("0"));
expect(await ethers.provider.getCode(tokenLock.address)).to.equal("0x");
});

it("cannot revoke after renaunceOwnership revoke", async () => {
await setup(accounts);
await tokenLock.renounceOwnership();
Expand Down

0 comments on commit 19117c0

Please sign in to comment.