vault: only allow deposit, transfer, etc when locked

This commit is contained in:
Mark Spanbroek 2025-02-03 16:26:51 +01:00
parent 3864559d85
commit 6e531f2087
2 changed files with 81 additions and 4 deletions

View File

@ -79,9 +79,18 @@ abstract contract VaultBase {
address from,
uint128 amount
) internal {
Lock memory lock = _locks[controller][context];
require(lock.isLocked(), LockRequired());
Recipient recipient = Recipient.wrap(from);
_balances[controller][context][recipient].available += amount;
_locks[controller][context].value += amount;
Balance memory balance = _balances[controller][context][recipient];
balance.available += amount;
lock.value += amount;
_balances[controller][context][recipient] = balance;
_locks[controller][context] = lock;
_token.safeTransferFrom(from, address(this), amount);
}
@ -123,6 +132,7 @@ abstract contract VaultBase {
Recipient recipient
) internal {
Lock memory lock = _locks[controller][context];
require(lock.isLocked(), LockRequired());
Flow memory flow = _flows[controller][context][recipient];
require(flow.rate == TokensPerSecond.wrap(0), CannotBurnFlowingTokens());
@ -150,6 +160,9 @@ abstract contract VaultBase {
Recipient to,
uint128 amount
) internal {
Lock memory lock = _locks[controller][context];
require(lock.isLocked(), LockRequired());
Balance memory senderBalance = _getBalance(controller, context, from);
Balance memory receiverBalance = _getBalance(controller, context, to);
require(amount <= senderBalance.available, InsufficientBalance());
@ -158,7 +171,6 @@ abstract contract VaultBase {
receiverBalance.available += amount;
Flow memory senderFlow = _flows[controller][context][from];
Lock memory lock = _locks[controller][context];
_checkFlowInvariant(senderBalance, lock, senderFlow);
_balances[controller][context][from] = senderBalance;
@ -171,6 +183,9 @@ abstract contract VaultBase {
Recipient recipient,
uint128 amount
) internal {
Lock memory lock = _locks[controller][context];
require(lock.isLocked(), LockRequired());
Balance memory balance = _balances[controller][context][recipient];
require(amount <= balance.available, InsufficientBalance());
@ -178,7 +193,6 @@ abstract contract VaultBase {
balance.designated += amount;
Flow memory flow = _flows[controller][context][recipient];
Lock memory lock = _locks[controller][context];
_checkFlowInvariant(balance, lock, flow);
_balances[controller][context][recipient] = balance;

View File

@ -56,12 +56,37 @@ describe("Vault", function () {
).to.be.revertedWith("LockRequired")
})
it("does not allow depositing of tokens", async function () {
const amount = 1000
await token.connect(account).approve(vault.address, amount)
await expect(
vault.deposit(context, account.address, amount)
).to.be.revertedWith("LockRequired")
})
it("does not allow designating tokens", async function () {
await expect(
vault.designate(context, account.address, 0)
).to.be.revertedWith("LockRequired")
})
it("does not allow transfer of tokens", async function () {
await expect(
vault.transfer(context, account.address, account2.address, 0)
).to.be.revertedWith("LockRequired")
})
it("does not allow flowing of tokens", async function () {
await expect(
vault.flow(context, account.address, account2.address, 0)
).to.be.revertedWith("LockRequired")
})
it("does not allow burning of tokens", async function () {
await expect(vault.burn(context, account.address)).to.be.revertedWith(
"LockRequired"
)
})
})
describe("when lock is locked", function () {
@ -143,6 +168,8 @@ describe("Vault", function () {
it("separates deposits from different contexts", async function () {
const context1 = randomBytes(32)
const context2 = randomBytes(32)
await vault.lock(context1, expiry, maximum)
await vault.lock(context2, expiry, maximum)
await token.connect(account).approve(vault.address, 3)
await vault.deposit(context1, account.address, 1)
await vault.deposit(context2, account.address, 2)
@ -154,6 +181,8 @@ describe("Vault", function () {
const [, , controller1, controller2] = await ethers.getSigners()
const vault1 = vault.connect(controller1)
const vault2 = vault.connect(controller2)
await vault1.lock(context, expiry, maximum)
await vault2.lock(context, expiry, maximum)
await token.connect(account).approve(vault.address, 3)
await vault1.deposit(context, account.address, 1)
await vault2.deposit(context, account.address, 2)
@ -689,5 +718,39 @@ describe("Vault", function () {
expect(after).to.equal(before)
})
})
it("does not allow depositing of tokens", async function () {
setAutomine(true)
await expire()
const amount = 1000
await token.connect(account).approve(vault.address, amount)
await expect(
vault.deposit(context, account.address, amount)
).to.be.revertedWith("LockRequired")
})
it("does not allow designating tokens", async function () {
setAutomine(true)
await expire()
await expect(
vault.designate(context, account.address, 0)
).to.be.revertedWith("LockRequired")
})
it("does not allow transfer of tokens", async function () {
setAutomine(true)
await expire()
await expect(
vault.transfer(context, account.address, account2.address, 0)
).to.be.revertedWith("LockRequired")
})
it("does not allow burning of tokens", async function () {
setAutomine(true)
await expire()
await expect(vault.burn(context, account.address)).to.be.revertedWith(
"LockRequired"
)
})
})
})