102 lines
2.7 KiB
Ruby
102 lines
2.7 KiB
Ruby
methods {
|
|
balanceOf(address) returns (uint) envfree;
|
|
ownerOf(uint256 tokenId) returns (address) envfree;
|
|
transferable() returns (bool) envfree;
|
|
totalSupply() returns (uint) envfree;
|
|
owner() returns (address) envfree;
|
|
maxSupply() returns (uint) envfree;
|
|
}
|
|
|
|
/* rule sanity(env e, method f) { */
|
|
/* calldataarg args; */
|
|
/* f(e, args); */
|
|
/* assert false; */
|
|
/* } */
|
|
|
|
rule mintTo_FromOwner {
|
|
address owner;
|
|
address recipient_1;
|
|
address recipient_2;
|
|
|
|
env e;
|
|
require recipient_1 != recipient_2;
|
|
require e.msg.sender == owner;
|
|
require owner() == owner;
|
|
require maxSupply() == 100000;
|
|
require totalSupply() == 0;
|
|
require balanceOf(recipient_1) == 0;
|
|
require balanceOf(recipient_2) == 0;
|
|
|
|
assert balanceOf(recipient_1) == 0, "balance of recipient_1 should be 0";
|
|
assert balanceOf(recipient_2) == 0, "balance of recipient_2 should be 0";
|
|
|
|
mintTo(e, [recipient_1, recipient_2]);
|
|
|
|
assert balanceOf(recipient_1) == 1, "balance of recipient_1 should be 1";
|
|
assert balanceOf(recipient_2) == 1, "balance of recipient_2 should be 1";
|
|
}
|
|
|
|
rule transferNFT_validOwner {
|
|
address sender;
|
|
address recipient;
|
|
uint token_id;
|
|
|
|
env e;
|
|
require e.msg.sender == sender;
|
|
require sender != recipient;
|
|
require ownerOf(token_id) == sender;
|
|
require transferable() == true;
|
|
|
|
mathint balance_sender_before = balanceOf(sender);
|
|
mathint balance_recipient_before = balanceOf(recipient);
|
|
|
|
transferFrom(e, sender, recipient, token_id);
|
|
|
|
assert ownerOf(token_id) == recipient;
|
|
assert balanceOf(sender) == balance_sender_before - 1;
|
|
/* assert balanceOf(recipient) == balance_recipient_before + 1; */
|
|
}
|
|
|
|
rule transferNFT_invalidOwner {
|
|
address sender;
|
|
address recipient;
|
|
uint token_id;
|
|
|
|
env e;
|
|
require e.msg.sender == sender;
|
|
require sender != recipient;
|
|
require ownerOf(token_id) != sender;
|
|
require transferable() == true;
|
|
|
|
transferFrom@withrevert(e, sender, recipient, token_id);
|
|
assert lastReverted, "transfer should revert when the sender is not the owner of tokenId";
|
|
}
|
|
|
|
rule transferSoulbound {
|
|
address sender;
|
|
address recipient;
|
|
uint token_id;
|
|
|
|
env e;
|
|
require e.msg.sender == sender;
|
|
require sender != recipient;
|
|
require ownerOf(token_id) == sender;
|
|
require transferable() == false;
|
|
|
|
mathint balance_sender_before = balanceOf(sender);
|
|
mathint balance_recipient_before = balanceOf(recipient);
|
|
|
|
transferFrom@withrevert(e, sender, recipient, token_id);
|
|
|
|
assert lastReverted, "transfer should revert if it's a Soulbound token";
|
|
}
|
|
|
|
rule maxSupplyNotLowerThanTotalSupply(env e, method f) {
|
|
require maxSupply() >= totalSupply();
|
|
|
|
calldataarg args;
|
|
f(e, args); // call all public/external functions of a contract
|
|
|
|
assert maxSupply() >= totalSupply();
|
|
}
|