Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions src/DeepstateGovernor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ contract DeepstateGovernor is
_setVotingPeriod(newVotingPeriod);
}

function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) {
function proposalThreshold() public view virtual override(Governor, GovernorSettings) returns (uint256) {
uint256 numerator = _proposalThresholdNumerator;
uint48 currentTimepoint = clock();
if (currentTimepoint == 0) return numerator == 0 ? 0 : 1;
Expand Down Expand Up @@ -148,7 +148,13 @@ contract DeepstateGovernor is
return super.propose(targets, values, calldatas, description);
}

function quorum(uint256 timepoint) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256) {
function quorum(uint256 timepoint)
public
view
virtual
override(Governor, GovernorVotesQuorumFraction)
returns (uint256)
{
return Math.max(super.quorum(timepoint), MINIMUM_QUORUM);
}

Expand Down
38 changes: 38 additions & 0 deletions src/DeepstateRewarder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,44 @@ contract DeepstateRewarder is Ownable, IHook {
balances[bookId][token][nonce] = 0;
}

/// @dev Checkpoint one live rewardee through the current timestamp, then permanently forget its cursor unless the
/// engine later installs another one. Derived rewarders call this only after the Router has stopped using them.
function _freezeRewardee(address token)
internal
returns (bytes32 bookId, uint32 orderNonce, uint256 checkpointedReward)
{
bool isToken0 = token == token0;
if (!isToken0 && token != token1) revert InvalidHookToken();

uint256 packed = isToken0 ? _token0State : _token1State;
uint64 topStartedAt;
uint64 activatedAt;
uint96 accrued;
(orderNonce, topStartedAt, activatedAt, accrued) = _unpackState(packed);
bookId = isToken0 ? _token0BookId : _token1BookId;

if (orderNonce != 0 && topStartedAt != 0 && activatedAt != 0 && block.timestamp > topStartedAt) {
(uint32 liveNonce, uint160 liveAmount) = IOrderBook(deepstate).topOrder(bookId, !isToken0);
if (liveNonce == orderNonce && liveAmount != 0) {
checkpointedReward = previewReward(token, topStartedAt, block.timestamp, liveAmount);
checkpointedReward = _remainingReward(accrued, checkpointedReward);
if (checkpointedReward != 0) {
balances[bookId][token][orderNonce] += checkpointedReward;
accrued += uint96(checkpointedReward);
}
}
}

uint256 frozenState = _packState(0, 0, activatedAt, accrued);
if (isToken0) {
_token0State = frozenState;
_token0BookId = bytes32(0);
} else {
_token1State = frozenState;
_token1BookId = bytes32(0);
}
}

function _resolveClaimant(bytes32 bookId, bytes32 order) private returns (address claimant) {
IOrderBook orderBook = IOrderBook(deepstate);
bytes32 id = orderBook.orderId(bookId, order);
Expand Down
2 changes: 1 addition & 1 deletion src/DeepstateToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract DeepstateToken is ERC20, AccessControl {
_grantRole(DEFAULT_ADMIN_ROLE, admin_);
}

function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
function mint(address to, uint256 amount) external virtual onlyRole(MINTER_ROLE) {
if (to == address(0)) revert ZeroAddress();
_mint(to, amount);
}
Expand Down