vault: reject flow when insufficient tokens available

This commit is contained in:
Mark Spanbroek 2025-01-23 14:28:17 +01:00
parent d9452a7ac2
commit 38f3a73c8f
2 changed files with 37 additions and 12 deletions

View File

@ -184,11 +184,13 @@ abstract contract VaultBase {
Recipient to,
TokensPerSecond rate
) internal {
require(
_getLock(controller, context).expiry != Timestamp.wrap(0),
LockRequired()
);
Lock memory lock = _getLock(controller, context);
require(lock.expiry != Timestamp.wrap(0), LockRequired());
Timestamp start = Timestamps.currentTime();
uint64 duration = Timestamp.unwrap(lock.maximum) - Timestamp.unwrap(start);
int256 total = int256(uint256(duration)) * TokensPerSecond.unwrap(rate);
Balance memory balance = _getBalance(controller, context, from);
require(total <= int256(balance.available), InsufficientBalance());
_flows[controller][context][to] = Flow({start: start, rate: rate});
_flows[controller][context][from] = Flow({start: start, rate: -rate});
}

View File

@ -383,14 +383,14 @@ describe("Vault", function () {
describe("flow", function () {
const context = randomBytes(32)
const amount = 42
const deposit = 100
let sender
let receiver
beforeEach(async function () {
await token.connect(account).approve(vault.address, amount)
await vault.deposit(context, account.address, amount)
await token.connect(account).approve(vault.address, deposit)
await vault.deposit(context, account.address, deposit)
sender = account.address
receiver = account2.address
})
@ -408,20 +408,22 @@ describe("Vault", function () {
describe("when a lock is set", async function () {
let expiry
let maximum
beforeEach(async function () {
expiry = (await currentTime()) + 20
await vault.lockup(context, expiry, expiry)
maximum = expiry + 10
await vault.lockup(context, expiry, maximum)
})
it("moves tokens over time", async function () {
await vault.flow(context, sender, receiver, 2)
const start = await currentTime()
await advanceTimeTo(start + 2)
expect(await vault.balance(context, sender)).to.equal(amount - 4)
expect(await vault.balance(context, sender)).to.equal(deposit - 4)
expect(await vault.balance(context, receiver)).to.equal(4)
await advanceTimeTo(start + 4)
expect(await vault.balance(context, sender)).to.equal(amount - 8)
expect(await vault.balance(context, sender)).to.equal(deposit - 8)
expect(await vault.balance(context, receiver)).to.equal(8)
})
@ -437,12 +439,33 @@ describe("Vault", function () {
const start = await currentTime()
await advanceTimeTo(expiry)
const total = (expiry - start) * 2
expect(await vault.balance(context, sender)).to.equal(amount - total)
expect(await vault.balance(context, sender)).to.equal(deposit - total)
expect(await vault.balance(context, receiver)).to.equal(total)
await advanceTimeTo(expiry + 10)
expect(await vault.balance(context, sender)).to.equal(amount - total)
expect(await vault.balance(context, sender)).to.equal(deposit - total)
expect(await vault.balance(context, receiver)).to.equal(total)
})
it("flows longer when lock is extended", async function () {
await vault.flow(context, sender, receiver, 2)
const start = await currentTime()
await vault.extend(context, maximum)
await advanceTimeTo(maximum)
const total = (maximum - start) * 2
expect(await vault.balance(context, sender)).to.equal(deposit - total)
expect(await vault.balance(context, receiver)).to.equal(total)
await advanceTimeTo(maximum + 10)
expect(await vault.balance(context, sender)).to.equal(deposit - total)
expect(await vault.balance(context, receiver)).to.equal(total)
})
it("rejects flow when insufficient available tokens", async function () {
const duration = maximum - await currentTime()
const rate = Math.round(deposit / duration)
await expect(
vault.flow(context, sender, receiver, rate + 1)
).to.be.revertedWith("InsufficientBalance")
})
})
})
})