Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use timestamp instead of block number in predictoor #780

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
7a4b92c
add setFeeCollector
alexcos20 Jul 27, 2023
beb6d1a
fix lint
alexcos20 Jul 27, 2023
a0ccf2b
add zero address check
alexcos20 Jul 27, 2023
3117b51
Use timestamp instead on block number
trizin Jul 28, 2023
a9b0213
Update tests
trizin Jul 28, 2023
fc5a0cf
Fix
trizin Jul 28, 2023
8178b30
Use epoch to calculate everything
trizin Jul 28, 2023
6996fd9
Update tests
trizin Jul 28, 2023
03161e0
Update tests
trizin Jul 28, 2023
a36fd83
Fix updateSeconds(
trizin Jul 28, 2023
949e651
Update tests for change in `updateSeconds`
trizin Jul 28, 2023
b1638f7
Add missing semicolon
trizin Jul 28, 2023
82e7702
Adjustments for epoch and fixes
trizin Jul 28, 2023
32a1d19
Adjustments and fixes
trizin Jul 28, 2023
3fe82b8
More adjustments and fixes
trizin Jul 28, 2023
4b2f4e0
Update tests
trizin Jul 28, 2023
1d4e2e7
Start epoch from 0
trizin Jul 29, 2023
4042b9b
Remove unused function
trizin Jul 29, 2023
8f03ea9
Add more comments
trizin Jul 29, 2023
b32870e
Try fix
trizin Jul 29, 2023
8f8e18e
Fix overflow
trizin Jul 29, 2023
32dd2d5
Make starttime public
trizin Jul 29, 2023
62890d9
Test fixes
trizin Jul 29, 2023
738d2ef
Update tests
trizin Jul 29, 2023
3b7e58c
Define undefined secondsPerEpoch
trizin Jul 29, 2023
7364279
Update some events
trizin Jul 29, 2023
e9c8152
Remove -1
trizin Jul 29, 2023
9f5969a
Fix tests
trizin Jul 29, 2023
8d8178c
Update contracts/templates/ERC20Template3.sol
trizin Jul 31, 2023
3073543
Update contracts/templates/ERC20Template3.sol
trizin Jul 31, 2023
1a00726
Update contracts/templates/ERC20Template3.sol
trizin Jul 31, 2023
8768f53
Update contracts/templates/ERC20Template3.sol
trizin Jul 31, 2023
95cdc06
Use timestamp as epoch number
trizin Jul 31, 2023
016d982
Update tests
trizin Jul 31, 2023
6db94ec
Merge branch 'issue779-use-timestamp-instead-of-block-number-in-predi…
trizin Jul 31, 2023
443c895
Fix
trizin Jul 31, 2023
9bce114
Merge branch 'issue779-use-timestamp-instead-of-block-number-in-predi…
trizin Jul 31, 2023
cd90f40
Fix merge error
trizin Jul 31, 2023
fc20d19
_epoch => epoch_start
trizin Aug 1, 2023
97128fb
trueValSubmitTimeoutEpoch => trueValSubmitTimeout
trizin Aug 1, 2023
2deb98f
Fix
trizin Aug 1, 2023
b2f2d7f
Linter and readability
trizin Aug 1, 2023
796fe91
Merge pull request #776 from oceanprotocol/feature/feeCollector_setter
alexcos20 Aug 1, 2023
dd78e36
Update event param name
trizin Aug 2, 2023
e82057d
deployment
alexcos20 Aug 3, 2023
f57872f
Merge pull request #790 from oceanprotocol/feature/deploy_predictoor3…
alexcos20 Aug 3, 2023
deb2eb8
2.0.0-next.3
alexcos20 Aug 3, 2023
ccd6dcd
Add template 3 abi
trizin Aug 3, 2023
ed63008
Let predictoors update their prediction
trizin Aug 3, 2023
73342f9
cannot modify stake amt
trizin Aug 3, 2023
c97a037
Fix
trizin Aug 3, 2023
09386b1
Fix
trizin Aug 3, 2023
725740c
Lint
trizin Aug 3, 2023
7e19947
Add a test
trizin Aug 3, 2023
ecccae7
Emit an event on update
trizin Aug 3, 2023
e1e1acf
Add more tests
trizin Aug 3, 2023
e2598f7
Fix test
trizin Aug 3, 2023
fdbf61a
Remove event
trizin Aug 4, 2023
9734008
Merge pull request #792 from oceanprotocol/issue791-predictoor-update…
trizin Aug 4, 2023
e58562c
v2.0.0-next.4
alexcos20 Aug 4, 2023
f865627
Hide stake amounts for prediction epoch & allow predictoors modify th…
trizin Aug 5, 2023
82ffeca
Fix
trizin Aug 5, 2023
a9fc804
Fix
trizin Aug 5, 2023
a9a8d7b
Fix
trizin Aug 5, 2023
ba6b777
Update duplicate prediction tests
trizin Aug 5, 2023
eace40b
Update aggpredval test
trizin Aug 5, 2023
a005336
Fix
trizin Aug 5, 2023
0ee2bb8
Fix
trizin Aug 5, 2023
9a7fa6b
Add getTotalStake function
trizin Aug 5, 2023
60149d8
Require predictions not closed
trizin Aug 5, 2023
92d0248
Fix
trizin Aug 5, 2023
68891b8
Fix
trizin Aug 5, 2023
0f928ff
Fix
trizin Aug 5, 2023
e0f18bf
Fix
trizin Aug 5, 2023
53fbd6a
Remove require
trizin Aug 5, 2023
87871b2
Fix
trizin Aug 5, 2023
32f8911
Fix approval
trizin Aug 5, 2023
a8a2fd5
Fix test
trizin Aug 5, 2023
b56297b
Fix transfer
trizin Aug 5, 2023
bfeaad1
Fix epoch ts
trizin Aug 5, 2023
82466d2
Fix test
trizin Aug 5, 2023
a13cc15
await fastforward command
trizin Aug 5, 2023
cb5f72a
Add tests for total stake function
trizin Aug 5, 2023
d30cc1f
Fix type error
trizin Aug 5, 2023
54b4d30
Set seconds per epoch to 300
trizin Aug 5, 2023
e93a368
Add a test for toEpochStart
trizin Aug 5, 2023
720bc34
Fix testes where hardcoded values are used
trizin Aug 5, 2023
5e75797
Require s_per_subscription % s_per_epoch == 0
trizin Aug 5, 2023
e7afa9f
Fix test
trizin Aug 5, 2023
5ba4ff6
Reentrancy precaution
trizin Aug 5, 2023
1ec635f
Merge pull request #794 from oceanprotocol/issue793-hide-stake-amount…
alexcos20 Aug 7, 2023
04dbf29
v2.0.0-next.5
alexcos20 Aug 7, 2023
0007360
expose agg predval after trueval
alexcos20 Aug 16, 2023
eeff4f6
Merge pull request #796 from oceanprotocol/feature/expose_agg_preds_a…
alexcos20 Aug 16, 2023
ba9d21b
v2.0.0-next.6
alexcos20 Aug 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 64 additions & 61 deletions contracts/templates/ERC20Template3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@
}

event SettingChanged(
uint256 blocksPerEpoch,
uint256 blocksPerSubscription,
uint256 secondsPerEpoch,
uint256 secondsPerSubscription,
uint256 trueValueSubmitTimeoutBlock,
address stakeToken
);
Expand All @@ -101,7 +101,7 @@
uint256 slot,
uint256 amountPerEpoch,
uint256 numEpochs,
uint256 blocksPerEpoch
uint256 secondsPerEpoch
);

// All mappings below are using slot as key.
Expand All @@ -111,13 +111,13 @@
mapping(uint256 => uint256) private roundSumStakes;
mapping(uint256 => bool) public trueValues; // true values submited by owner
mapping(uint256 => Status) public epochStatus; // status of each epoch
mapping(uint256 => uint256) private subscriptionRevenueAtBlock; //income registred
mapping(uint256 => uint256) private subscriptionRevenueAtSlot; //income registred
mapping(address => Subscription) public subscriptions; // valid subscription per user
address public feeCollector; //who will get FRE fees, slashes stakes, revenue per epoch if no predictoors
uint256 public blocksPerEpoch;
uint256 public secondsPerEpoch;
address public stakeToken;
uint256 public blocksPerSubscription;
uint256 public trueValSubmitTimeoutBlock;
uint256 public secondsPerSubscription;
uint256 public trueValSubmitTimeoutEpoch;
bool public paused = false;
// -------------------------- PREDICTOOR --------------------------

Expand Down Expand Up @@ -501,10 +501,10 @@
}
Subscription memory sub = Subscription(
consumer,
block.number + blocksPerSubscription
block.number + secondsPerSubscription
);
subscriptions[consumer] = sub;
emit NewSubscription(consumer, block.number + blocksPerSubscription,block.number);
emit NewSubscription(consumer, block.number + secondsPerSubscription,block.number);


burn(amount);
Expand Down Expand Up @@ -914,42 +914,46 @@
return subscriptions[user].expires <= block.number ? false : true;
}

function epoch(uint256 blocknum) public view returns (uint256) {
return blocknum / blocksPerEpoch;
function epoch(uint256 _timestamp) public view returns (uint256) {
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
return _timestamp / secondsPerEpoch;
}

function curEpoch() public view returns (uint256) {
return epoch(block.number);
return epoch(block.timestamp);
}

function railBlocknumToSlot(
uint256 blocknum
function railTimestampToSlot(
uint256 _timestamp

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

) public view returns (uint256) {
uint256 rounded = blocknum / blocksPerEpoch;
return (rounded * blocksPerEpoch);
uint256 rounded = _timestamp / secondsPerEpoch;
return (rounded * secondsPerEpoch);
}

Check warning

Code scanning / Slither

Divide before multiply Medium


function blocknumIsOnSlot(
uint256 blocknum
function timestampIsOnSlot(
uint256 _timestamp

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

Fixed Show fixed Hide fixed
) public view returns (bool) {
// a slot == beginning/end of an epoch
return blocknum == railBlocknumToSlot(blocknum);
return _timestamp == railTimestampToSlot(_timestamp);
}

Check warning

Code scanning / Slither

Dangerous strict equalities Medium

Check notice

Code scanning / Slither

Block timestamp Low

ERC20Template3.timestampIsOnSlot(uint256) uses timestamp for comparisons
Dangerous comparisons:
- _timestamp == railTimestampToSlot(_timestamp)

function soonestBlockToPredict(uint256 prediction_block) public view returns (uint256) {
function soonestTimestampToPredict(uint256 prediction_ts) public view returns (uint256) {

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

/*
Epoch i: predictoors submit predictedValue for the beginning of epoch i+2.
Predval is: "does trueValue go UP or DOWN between the start of epoch i+1 and the start of epoch i+2?"
Once epoch i ends, predictoors cannot submit predictedValues for epoch i+2
*/
return(railBlocknumToSlot(prediction_block)+ blocksPerEpoch * 2);
return(railTimestampToSlot(prediction_ts) + secondsPerEpoch * 2);

// assume current time is candle 1 + x seconds
// railTimestampToSlot(prediction_ts) returns candle 1 time
// so the function returns candle 3
}

function submittedPredval(
uint256 blocknum,
address predictoor
) public view returns (bool) {
uint256 slot = railBlocknumToSlot(blocknum);
uint256 slot = railTimestampToSlot(blocknum);
return predictions[slot][predictoor].predictoor != address(0);
}

Expand All @@ -961,24 +965,24 @@
uint256 validUntil;
}
function getAggPredval(
uint256 blocknum,
uint256 _timestamp,

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

userAuth calldata _userAuth
) public view returns (uint256, uint256) {
_checkUserAuthorization(_userAuth);
require(isValidSubscription(_userAuth.userAddress), "No subscription");
uint256 slot = railBlocknumToSlot(blocknum);
uint256 slot = railTimestampToSlot(_timestamp);
return (roundSumStakesUp[slot], roundSumStakes[slot]);
}

function getSubscriptionRevenueAtBlock(
uint256 blocknum
function getsubscriptionRevenueAtSlot(
uint256 _timestamp

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

) public view returns (uint256) {
uint256 slot = railBlocknumToSlot(blocknum);
return (subscriptionRevenueAtBlock[slot]);
uint256 slot = railTimestampToSlot(_timestamp);
return (subscriptionRevenueAtSlot[slot]);
}

function getPrediction(
uint256 blocknum,
uint256 _timestamp,

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

address predictoor,
userAuth calldata _userAuth
)
Expand All @@ -987,11 +991,11 @@
returns (Prediction memory prediction)
{
//allow predictoors to see their own submissions
if ( blocknum >=block.number){
if (_timestamp >=block.number){
_checkUserAuthorization(_userAuth);
require(predictoor == _userAuth.userAddress, "Not auth");
}
uint256 slot = railBlocknumToSlot(blocknum);
uint256 slot = railTimestampToSlot(_timestamp);
prediction = predictions[slot][predictoor];
}

Expand All @@ -1000,11 +1004,11 @@
function submitPredval(
bool predictedValue,
uint256 stake,
uint256 blocknum
uint256 _timestamp

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

) external {
require(paused == false, "paused");
uint256 slot = railBlocknumToSlot(blocknum);
require(slot >= soonestBlockToPredict(block.number), "too late to submit");
uint256 slot = railTimestampToSlot(_timestamp);
require(slot >= soonestTimestampToPredict(block.timestamp), "too late to submit");
require(!submittedPredval(slot, msg.sender), "already submitted");

predictions[slot][msg.sender] = Prediction(
Expand Down Expand Up @@ -1032,16 +1036,16 @@
}

function payout(
uint256 blocknum,
uint256 _timestamp,

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

address predictoor_addr
) public nonReentrant {
require(submittedPredval(blocknum, predictoor_addr), "not submitted");
uint256 slot = railBlocknumToSlot(blocknum);
require(submittedPredval(_timestamp, predictoor_addr), "not submitted");
uint256 slot = railTimestampToSlot(_timestamp);
Prediction memory predobj = predictions[slot][predictoor_addr];
if(predobj.paid) return; // just return if already paid, in order not to break payoutMultiple

// if OPF hasn't submitted trueValue in truval_submit_timeout blocks then cancel round
if (block.number > slot + trueValSubmitTimeoutBlock && epochStatus[slot]==Status.Pending){
if (block.timestamp > slot + trueValSubmitTimeoutEpoch && epochStatus[slot]==Status.Pending){
epochStatus[slot]=Status.Canceled;
}

Expand All @@ -1061,7 +1065,7 @@
? roundSumStakesUp[slot]
: roundSumStakes[slot] - roundSumStakesUp[slot];
if(swe > 0) {
uint256 revenue=getSubscriptionRevenueAtBlock(slot);
uint256 revenue = getsubscriptionRevenueAtSlot(slot);
payout_amt = predobj.stake * (roundSumStakes[slot] + revenue) / swe;
}
}
Expand All @@ -1082,16 +1086,16 @@
}

// ----------------------- ADMIN FUNCTIONS -----------------------
function redeemUnusedSlotRevenue(uint256 blocknum) external onlyERC20Deployer {
require(block.number > blocknum);
uint256 slot = railBlocknumToSlot(blocknum);
function redeemUnusedSlotRevenue(uint256 timestamp) external onlyERC20Deployer {
uint256 slot = railTimestampToSlot(timestamp);
require(block.timestamp > slot);
require(roundSumStakes[slot] == 0);
require(feeCollector != address(0), "Cannot send fees to address 0");
IERC20(stakeToken).safeTransfer(
feeCollector,
subscriptionRevenueAtBlock[slot]
subscriptionRevenueAtSlot[slot]
);
}

Check notice

Code scanning / Slither

Block timestamp Low



function pausePredictions() external onlyERC20Deployer {
Expand All @@ -1112,21 +1116,21 @@
/**
* @dev submitTrueVal
* Called by owner to settle one epoch
* @param blocknum epoch block number
* @param _timestamp epoch block number
* @param trueValue trueValue for that epoch (0 - down, 1 - up)
* @param floatValue float value of pair for that epoch
* @param cancelRound If true, cancel that epoch
*/
function submitTrueVal(
uint256 blocknum,
uint256 _timestamp,

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

bool trueValue,
uint256 floatValue,
bool cancelRound
) external onlyERC20Deployer {
require(blocknum < block.number, "too early to submit");
uint256 slot = railBlocknumToSlot(blocknum);
require(_timestamp < block.timestamp, "too early to submit");
uint256 slot = railTimestampToSlot(_timestamp);
require(epochStatus[slot]==Status.Pending, "already settled");
if (cancelRound || (block.number > slot + trueValSubmitTimeoutBlock && epochStatus[slot]==Status.Pending)){
if (cancelRound || (block.timestamp > slot + trueValSubmitTimeoutEpoch && epochStatus[slot] == Status.Pending)){
epochStatus[slot]=Status.Canceled;
}
else{
Expand Down Expand Up @@ -1174,30 +1178,29 @@
require(s_per_subscription % s_per_block == 0, "%");
require(s_per_epoch % s_per_block == 0, "%");

if (blocksPerEpoch == 0) {
blocksPerEpoch = s_per_epoch / s_per_block; // immutaable
if (secondsPerEpoch == 0) {
secondsPerEpoch = s_per_epoch / s_per_block; // immutaable
}

blocksPerSubscription = s_per_subscription / s_per_block;
trueValSubmitTimeoutBlock = _truval_submit_timeout / s_per_block;
emit SettingChanged(blocksPerEpoch,blocksPerSubscription,trueValSubmitTimeoutBlock,stakeToken);
secondsPerSubscription = s_per_subscription / s_per_block;
trueValSubmitTimeoutEpoch = _truval_submit_timeout / s_per_block;
emit SettingChanged(secondsPerEpoch,secondsPerSubscription,trueValSubmitTimeoutEpoch,stakeToken);
}

function add_revenue(uint256 blocknum, uint256 amount) internal {
function add_revenue(uint256 _timestamp, uint256 amount) internal {

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

if (amount > 0) {
uint256 slot = railBlocknumToSlot(blocknum);
uint256 num_epochs = blocksPerSubscription / blocksPerEpoch;
uint256 slot = railTimestampToSlot(_timestamp);
uint256 num_epochs = secondsPerSubscription / secondsPerEpoch;
if(num_epochs<1)
num_epochs=1;
uint256 amt_per_epoch = amount / num_epochs;
// for loop and add revenue for blocksPerEpoch blocks
// for loop and add revenue for secondsPerEpoch blocks
for (uint256 i = 0; i < num_epochs; i++) {
// TODO FIND A WAY TO ACHIEVE THIS WITHOUT A LOOP
subscriptionRevenueAtBlock[
slot + blocksPerEpoch * (i)
subscriptionRevenueAtSlot[
slot * secondsPerEpoch * (i)
] += amt_per_epoch;
}
emit RevenueAdded(amount,slot,amt_per_epoch,num_epochs,blocksPerEpoch);
emit RevenueAdded(amount,slot,amt_per_epoch,num_epochs,secondsPerEpoch);
}
}

Check warning

Code scanning / Slither

Conformance to Solidity naming conventions Warning

Function ERC20Template3.add_revenue(uint256,uint256) is not in mixedCase

Expand Down
Loading
Loading