function queue(uint proposalId) public {
require(state(proposalId) == ProposalState.Succeeded, "GovernorAlpha::queue: proposal can only be queued if it is succeeded");
Proposal storage proposal = proposals[proposalId];
uint eta = add256(block.timestamp, timelock.delay());
for (uint i = 0; i < proposal.targets.length; i++) {
_queueOrRevert(proposal.targets[i], proposal.values[i], proposal.signatures[i], proposal.calldatas[i], eta);
}
proposal.eta = eta;
emit ProposalQueued(proposalId, eta);
}
0x6a04f47f839d6db81ba06b17b5abbc8b250b4c62e81f4a64aa6b04c0568dc501 Transfer 17634604 4 days 16 hrs ago Fotress Protocol Exploiter OUT MahaDAO: MAHA Token 0 BNB 0.00020393
0xd127c438bdac59e448810b812ffc8910bbefc3ebf280817bd2ed1e57705588a0 Transfer 17634599 4 days 16 hrs ago Fotress Protocol Exploiter OUT Fortress Protocol: FTS Token 0 BNB 0.00045206
function submit(
uint32 _dataTimestamp,
bytes32 _root,
bytes32[] memory _keys,
uint256[] memory _values,
uint8[] memory _v,
bytes32[] memory _r,
bytes32[] memory _s
) public { // it could be external, but for external we got stack too deep
uint32 lastBlockId = getLatestBlockId();
uint32 dataTimestamp = squashedRoots[lastBlockId].extractTimestamp();
require(dataTimestamp + padding < block.timestamp, "do not spam");
require(dataTimestamp < _dataTimestamp, "can NOT submit older data");
// we can't expect minter will have exactly the same timestamp
// but for sure we can demand not to be off by a lot, that's why +3sec
// temporary remove this condition, because recently on ropsten we see cases when minter/node
// can be even 100sec behind
// require(_dataTimestamp <= block.timestamp + 3,
// string(abi.encodePacked("oh, so you can predict the future:", _dataTimestamp - block.timestamp + 48)));
require(_keys.length == _values.length, "numbers of keys and values not the same");
bytes memory testimony = abi.encodePacked(_dataTimestamp, _root);
for (uint256 i = 0; i < _keys.length; i++) {
require(uint224(_values[i]) == _values[i], "FCD overflow");
fcds[_keys[i]] = FirstClassData(uint224(_values[i]), _dataTimestamp);
testimony = abi.encodePacked(testimony, _keys[i], _values[i]);
}
bytes32 affidavit = keccak256(testimony);
uint256 power = 0;
uint256 staked = stakingBank.totalSupply();
address prevSigner = address(0x0);
uint256 i = 0;
for (; i < _v.length; i++) {
address signer = recoverSigner(affidavit, _v[i], _r[i], _s[i]);
uint256 balance = stakingBank.balanceOf(signer);
require(prevSigner < signer, "validator included more than once");
prevSigner = signer;
if (balance == 0) continue;
emit LogVoter(lastBlockId + 1, signer, balance);
power += balance; // no need for safe math, if we overflow then we will not have enough power
}
require(i >= requiredSignatures, "not enough signatures");
// we turn on power once we have proper DPoS
// require(power * 100 / staked >= 66, "not enough power was gathered");
squashedRoots[lastBlockId + 1] = _root.makeSquashedRoot(_dataTimestamp);
blocksCount++;
emit LogMint(msg.sender, lastBlockId + 1, staked, power);
}