mirror of
https://github.com/status-im/codex-contracts-eth.git
synced 2025-02-12 08:26:46 +00:00
vault: change flows over time
This commit is contained in:
parent
82467f101d
commit
421a1eb5ba
@ -11,6 +11,7 @@ using {_tokensPerSecondPlus as +} for TokensPerSecond global;
|
|||||||
using {_tokensPerSecondEquals as ==} for TokensPerSecond global;
|
using {_tokensPerSecondEquals as ==} for TokensPerSecond global;
|
||||||
using {_tokensPerSecondNotEqual as !=} for TokensPerSecond global;
|
using {_tokensPerSecondNotEqual as !=} for TokensPerSecond global;
|
||||||
using {_tokensPerSecondAtLeast as >=} for TokensPerSecond global;
|
using {_tokensPerSecondAtLeast as >=} for TokensPerSecond global;
|
||||||
|
using {_tokensPerSecondLessThan as <} for TokensPerSecond global;
|
||||||
|
|
||||||
function _tokensPerSecondNegate(
|
function _tokensPerSecondNegate(
|
||||||
TokensPerSecond rate
|
TokensPerSecond rate
|
||||||
@ -54,3 +55,10 @@ function _tokensPerSecondAtLeast(
|
|||||||
) pure returns (bool) {
|
) pure returns (bool) {
|
||||||
return TokensPerSecond.unwrap(a) >= TokensPerSecond.unwrap(b);
|
return TokensPerSecond.unwrap(a) >= TokensPerSecond.unwrap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _tokensPerSecondLessThan(
|
||||||
|
TokensPerSecond a,
|
||||||
|
TokensPerSecond b
|
||||||
|
) pure returns (bool) {
|
||||||
|
return TokensPerSecond.unwrap(a) < TokensPerSecond.unwrap(b);
|
||||||
|
}
|
||||||
|
@ -179,22 +179,36 @@ abstract contract VaultBase {
|
|||||||
Lock memory lock = _locks[controller][context];
|
Lock memory lock = _locks[controller][context];
|
||||||
require(lock.isLocked(), LockRequired());
|
require(lock.isLocked(), LockRequired());
|
||||||
|
|
||||||
Timestamp start = Timestamps.currentTime();
|
Balance memory senderBalance = _getBalance(controller, context, from);
|
||||||
|
Balance memory receiverBalance = _getBalance(controller, context, to);
|
||||||
Flow memory senderFlow = _flows[controller][context][from];
|
Flow memory senderFlow = _flows[controller][context][from];
|
||||||
|
Flow memory receiverFlow = _flows[controller][context][to];
|
||||||
|
|
||||||
|
Timestamp start = Timestamps.currentTime();
|
||||||
senderFlow.start = start;
|
senderFlow.start = start;
|
||||||
senderFlow.rate = senderFlow.rate - rate;
|
senderFlow.rate = senderFlow.rate - rate;
|
||||||
Flow memory receiverFlow = _flows[controller][context][to];
|
|
||||||
receiverFlow.start = start;
|
receiverFlow.start = start;
|
||||||
receiverFlow.rate = receiverFlow.rate + rate;
|
receiverFlow.rate = receiverFlow.rate + rate;
|
||||||
|
|
||||||
Balance memory senderBalance = _getBalance(controller, context, from);
|
_checkFlowInvariant(senderBalance, lock, senderFlow);
|
||||||
uint128 flowMaximum = uint128(-senderFlow._totalAt(lock.maximum));
|
|
||||||
require(flowMaximum <= senderBalance.available, InsufficientBalance());
|
|
||||||
|
|
||||||
|
_balances[controller][context][from] = senderBalance;
|
||||||
|
_balances[controller][context][to] = receiverBalance;
|
||||||
_flows[controller][context][from] = senderFlow;
|
_flows[controller][context][from] = senderFlow;
|
||||||
_flows[controller][context][to] = receiverFlow;
|
_flows[controller][context][to] = receiverFlow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _checkFlowInvariant(
|
||||||
|
Balance memory balance,
|
||||||
|
Lock memory lock,
|
||||||
|
Flow memory flow
|
||||||
|
) private pure {
|
||||||
|
if (flow.rate < TokensPerSecond.wrap(0)) {
|
||||||
|
uint128 outgoing = uint128(-flow._totalAt(lock.maximum));
|
||||||
|
require(outgoing <= balance.available, InsufficientBalance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error InsufficientBalance();
|
error InsufficientBalance();
|
||||||
error Locked();
|
error Locked();
|
||||||
error AlreadyLocked();
|
error AlreadyLocked();
|
||||||
|
@ -418,7 +418,6 @@ describe("Vault", function () {
|
|||||||
return await vault.getBalance(context, recipient)
|
return await vault.getBalance(context, recipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
it("requires that a lock is set", async function () {
|
it("requires that a lock is set", async function () {
|
||||||
await expect(vault.flow(context, sender, receiver, 2)).to.be.revertedWith(
|
await expect(vault.flow(context, sender, receiver, 2)).to.be.revertedWith(
|
||||||
"LockRequired"
|
"LockRequired"
|
||||||
@ -471,6 +470,28 @@ describe("Vault", function () {
|
|||||||
expect(await getBalance(receiver2)).to.equal(8)
|
expect(await getBalance(receiver2)).to.equal(8)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("can change flows over time", async function () {
|
||||||
|
await setAutomine(false)
|
||||||
|
await vault.flow(context, sender, receiver, 1)
|
||||||
|
await vault.flow(context, sender, receiver2, 2)
|
||||||
|
await mine()
|
||||||
|
const start = await currentTime()
|
||||||
|
advanceTimeTo(start + 4)
|
||||||
|
await vault.flow(context, receiver2, receiver, 1)
|
||||||
|
await mine()
|
||||||
|
expect(await getBalance(sender)).to.equal(deposit - 12)
|
||||||
|
expect(await getBalance(receiver)).to.equal(4)
|
||||||
|
expect(await getBalance(receiver2)).to.equal(8)
|
||||||
|
await advanceTimeTo(start + 8)
|
||||||
|
expect(await getBalance(sender)).to.equal(deposit - 24)
|
||||||
|
expect(await getBalance(receiver)).to.equal(12)
|
||||||
|
expect(await getBalance(receiver2)).to.equal(12)
|
||||||
|
await advanceTimeTo(start + 12)
|
||||||
|
expect(await getBalance(sender)).to.equal(deposit - 36)
|
||||||
|
expect(await getBalance(receiver)).to.equal(20)
|
||||||
|
expect(await getBalance(receiver2)).to.equal(16)
|
||||||
|
})
|
||||||
|
|
||||||
it("designates tokens that flow for the recipient", async function () {
|
it("designates tokens that flow for the recipient", async function () {
|
||||||
await vault.flow(context, sender, receiver, 3)
|
await vault.flow(context, sender, receiver, 3)
|
||||||
const start = await currentTime()
|
const start = await currentTime()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user