Updates to the VariableDebtToken spec

This commit is contained in:
pistiner 2020-11-22 22:20:43 +02:00
parent 5ad4182508
commit dd0e3064e3
2 changed files with 88 additions and 87 deletions

View File

@ -1,10 +1,7 @@
using LendingPoolHarnessForVariableDebtToken as POOL
/**
TotalSupply is the sum of all users balances
totalSupply(t) = Σaddress u. balanceOf(u,t)
Check that each possible opertaion changes the balance of at most one user
Checks that each possible opertaion changes the balance of at most one user.
*/
rule balanceOfChange(address a, address b, method f)
{
@ -22,10 +19,10 @@ rule balanceOfChange(address a, address b, method f)
assert (balanceABefore == balanceAAfter || balanceBBefore == balanceBAfter);
}
/*
Check that the changed to total supply is coherent with the changes to balance
/**
Checks that the change to total supply is coherent with the change to the balance due to an operation
(which is neither a burn nor a mint).
*/
rule integirtyBalanceOfTotalSupply(address a, method f)
{
env e;
@ -36,17 +33,17 @@ rule integirtyBalanceOfTotalSupply(address a, method f )
calldataarg arg;
sinvoke f(e, arg);
require (f.selector != burn(address, uint256, uint256).selector &&
f.selector != mint(address, uint256, uint256).selector ) ;
f.selector != mint(address, address, uint256, uint256).selector);
uint256 balanceAAfter = balanceOf(e, a);
uint256 totalSupplyAfter = totalSupply(e);
assert (balanceAAfter != balanceABefore => ( balanceAAfter - balanceABefore == totalSupplyAfter - totalSupplyBefore));
}
/* Burn behaves deferently and due to accumulation errors might hace less total supply then the balance
/**
Checks that the change to total supply is coherent with the change to the balance due to a burn operation.
*/
rule integirtyBalanceOfTotalSupplyOnBurn(address a, method f )
rule integirtyBalanceOfTotalSupplyOnBurn(address a)
{
env e;
@ -62,64 +59,72 @@ rule integirtyBalanceOfTotalSupplyOnBurn(address a, method f )
assert (balanceAAfter != balanceABefore => (balanceAAfter - balanceABefore == totalSupplyAfter - totalSupplyBefore));
}
rule integirtyBalanceOfTotalSupplyOnMint(address a, method f )
/**
Checks that the change to total supply is coherent with the change to the balance due to a mint operation.
*/
rule integirtyBalanceOfTotalSupplyOnMint(address u, address delegatedUser)
{
env e;
uint256 balanceABefore = balanceOf(e, a);
uint256 balanceUBefore = balanceOf(e, u);
uint256 totalSupplyBefore = totalSupply(e);
uint256 x;
address asset;
uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);
sinvoke mint(e, a, x, index);
uint256 balanceAAfter = balanceOf(e, a);
sinvoke mint(e, delegatedUser, u, x, index);
uint256 balanceUAfter = balanceOf(e, u);
uint256 totalSupplyAfter = totalSupply(e);
assert (balanceAAfter != balanceABefore => ( balanceAAfter - balanceABefore == totalSupplyAfter - totalSupplyBefore));
assert (balanceUAfter != balanceUBefore => (balanceUAfter - balanceUBefore == totalSupplyAfter - totalSupplyBefore));
}
/**
Minting an amount of x tokens for user u increases their balance by x, up to rounding errors.
Minting an amount of x tokens for user u increases her balance by x, up to rounding errors.
{ b = balanceOf(u,t) }
mint(u,x,index)
{ balanceOf(u,t) = b + x }
mint(delegatedUser, u, x, index)
{ balanceOf(u,t) = b + x }.
Also, if the minting is done by a user delegatedUser different than u, the balance of delegatedUser
remains unchanged.
*/
rule integrityMint(address a, uint256 x) {
rule integrityMint(address u, address delegatedUser, uint256 x) {
env e;
address asset;
uint256 index = POOL.getReserveNormalizedVariableDebt(e,asset);
uint256 balancebefore = balanceOf(e, a);
sinvoke mint(e, a, x, index);
uint256 balanceUBefore = balanceOf(e, u);
uint256 balanceDelegatedUBefore = balanceOf(e, delegatedUser);
sinvoke mint(e, delegatedUser, u, x, index);
uint256 balanceAfter = balanceOf(e, a);
assert balanceAfter == balancebefore+x;
uint256 balanceUAfter = balanceOf(e, u);
uint256 balanceDelegatedUAfter = balanceOf(e, delegatedUser);
assert balanceUAfter == balanceUBefore + x && (u != delegatedUser => (balanceDelegatedUAfter == balanceDelegatedUBefore));
}
/**
Mint is additive, can performed either all at once or gradually
mint(u,x); mint(u,y) ~ mint(u,x+y) at the same timestamp
Mint is additive, namely it can performed either all at once or gradually:
mint(delegatedUser, u, x, index); mint(delegatedUser, u, y, index) ~ mint(delegatedUser, u, x+y, index) at the same timestamp.
*/
rule additiveMint(address a, uint256 x, uint256 y) {
rule additiveMint(address a, address delegatedUser, uint256 x, uint256 y) {
env e;
address asset;
uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);
storage initialStorage = lastStorage;
sinvoke mint(e, a, x, index);
sinvoke mint(e, a, y, index);
sinvoke mint(e, delegatedUser, a, x, index);
sinvoke mint(e, delegatedUser, a, y, index);
uint256 balanceScenario1 = balanceOf(e, a);
uint t = x + y;
sinvoke mint(e, a, t ,index) at initialStorage;
uint256 t = x + y;
sinvoke mint(e, delegatedUser, a, t ,index) at initialStorage;
uint256 balanceScenario2 = balanceOf(e, a);
assert balanceScenario1 == balanceScenario2, "mint is not additive";
}
/**
Transfer of x amount of tokens from user u where receiver is user u
Burning an amount of x tokens for user u decreases her balance by x, up to rounding errors.
{ bu = balanceOf(u) }
burn(u, u, x)
{balanceOf(u) = bu - x }
burn(u, x)
{ balanceOf(u) = bu - x }.
*/
rule integrityBurn(address a, uint256 x) {
env e;
@ -132,9 +137,8 @@ rule integrityBurn(address a, uint256 x) {
assert balanceAfter == balancebefore - x;
}
/**
Minting is additive, i.e., it can be performed either all at once or in steps.
burn(u, u, x); burn(u, u, y) ~ burn(u, u, x+y)
Minting is additive, i.e., it can be performed either all at once or in steps:
burn(u, x); burn(u, y) ~ burn(u, x+y) at the same timestamp.
*/
rule additiveBurn(address a, uint256 x, uint256 y) {
env e;
@ -144,7 +148,7 @@ rule additiveBurn(address a, uint256 x, uint256 y) {
sinvoke burn(e, a, x, index);
sinvoke burn(e, a, y, index);
uint256 balanceScenario1 = balanceOf(e, a);
uint t = x + y;
uint256 t = x + y;
sinvoke burn(e, a, t ,index) at initialStorage;
uint256 balanceScenario2 = balanceOf(e, a);
@ -152,22 +156,19 @@ rule additiveBurn(address a, uint256 x, uint256 y) {
}
/**
Minting and burning are inverse operations.
Minting and burning are inverse operations:
{ bu = balanceOf(u) }
mint(u,x); burn(u, u, x)
{balanceOf(u) = bu }
{ balanceOf(u) = bu }.
*/
rule inverseMintBurn(address a, uint256 x) {
env e;
address asset;
address delegatedUser;
uint256 index = POOL.getReserveNormalizedVariableDebt(e, asset);
uint256 balancebefore = balanceOf(e, a);
sinvoke mint(e, a, x, index);
sinvoke mint(e, delegatedUser, a, x, index);
sinvoke burn(e, a, x, index);
uint256 balanceAfter = balanceOf(e, a);
assert balancebefore == balanceAfter, "burn is not inverse of mint";
assert balancebefore == balanceAfter, "burn is not the inverse of mint";
}