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

fix: thawing tokens #44

Merged
merged 24 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8765757
feat: deploy HorizonAccountingExtension
0xJabberwock Sep 23, 2024
e05ece5
refactor: revise max verifier cut and min thawing period
0xJabberwock Sep 24, 2024
98752b6
test: stake GRT and create provisions
0xJabberwock Sep 25, 2024
59593a5
test: set max thawing period
0xJabberwock Sep 25, 2024
4cdbddc
test: remove The Graph Controller
0xJabberwock Sep 25, 2024
af0a946
fix: conform with IAccountingExtension interface
0xJabberwock Sep 25, 2024
845f0a3
test: integrate HorizonAccountingExtension
0xJabberwock Sep 25, 2024
cf7e664
chore: merge dev branch
0xJabberwock Sep 25, 2024
18dceb3
chore: merge dev branch
0xJabberwock Oct 3, 2024
cec6226
feat: instantiate authorized callers in deployment script
0xJabberwock Oct 3, 2024
a79426e
test: integrate HorizonAccountingExtension with bond escalation
0xJabberwock Oct 3, 2024
850c1c7
feat: null payment amount
0xJabberwock Oct 3, 2024
b7cd5fd
fix: unbond slashed pledgers
0xJabberwock Oct 7, 2024
c9b283e
perf: wipe pledgers list after last escalation reward claim
0xJabberwock Oct 7, 2024
544f7ac
feat: remove releasePledge()
0xJabberwock Oct 7, 2024
665c755
feat: remove getPledgers()
0xJabberwock Oct 7, 2024
541d5de
fix: thawing tokens
0xShaito Oct 10, 2024
de2a208
test: unit
0xShaito Oct 11, 2024
4dd8ef5
fix: testing and pr
0xShaito Oct 14, 2024
c450176
test: integration
0xShaito Oct 14, 2024
e7ca907
test: add test for insufficient bonded tokens
0xShaito Oct 15, 2024
a41175e
Merge branch 'dev' into fix/thawing-tokens
0xShaito Oct 17, 2024
e424e64
test: add back thawing test
0xShaito Oct 17, 2024
2cdff77
fix: merge with dev
ashitakah Oct 17, 2024
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
1 change: 1 addition & 0 deletions script/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ address constant _ARBITRUM_SEPOLIA_COUNCIL = address(0x101);

// Data
uint64 constant _MIN_THAWING_PERIOD = 3 days;
uint128 constant _MAX_USERS_TO_CHECK = 10;
6 changes: 4 additions & 2 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
_ARBITRUM_SEPOLIA_EPOCH_MANAGER,
_ARBITRUM_SEPOLIA_GRAPH_TOKEN,
_ARBITRUM_SEPOLIA_HORIZON_STAKING,
_MAX_USERS_TO_CHECK,
_MIN_THAWING_PERIOD
} from 'script/Constants.sol';

Expand Down Expand Up @@ -145,8 +146,9 @@ contract Deploy is Script {

// Deploy `HorizonAccountingExtension`
address[] memory _authorizedCallers = _instantiateAuthorizedCallers();
horizonAccountingExtension =
new HorizonAccountingExtension(horizonStaking, oracle, graphToken, _MIN_THAWING_PERIOD, _authorizedCallers);
horizonAccountingExtension = new HorizonAccountingExtension(
horizonStaking, oracle, graphToken, arbitrable, _MIN_THAWING_PERIOD, _MAX_USERS_TO_CHECK, _authorizedCallers
);
console.log('`HorizonAccountingExtension` deployed at:', address(horizonAccountingExtension));

// Deploy `CouncilArbitrator`
Expand Down
24 changes: 21 additions & 3 deletions src/contracts/HorizonAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
IERC20 public immutable GRT;

/// @inheritdoc IHorizonAccountingExtension
uint64 public immutable MIN_THAWING_PERIOD;
IArbitrable public immutable ARBITRABLE;

/// @inheritdoc IHorizonAccountingExtension
uint32 public constant MAX_VERIFIER_CUT = 1_000_000;
uint64 public immutable MIN_THAWING_PERIOD;

/// @inheritdoc IHorizonAccountingExtension
uint32 public constant MAX_USERS_TO_SLASH = 1;
Expand Down Expand Up @@ -81,7 +81,9 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
IHorizonStaking _horizonStaking,
IOracle _oracle,
IERC20 _grt,
IArbitrable _arbitrable,
uint64 _minThawingPeriod,
uint128 _maxUsersToCheck,
address[] memory _authorizedCallers
) Validator(_oracle) {
HORIZON_STAKING = _horizonStaking;
Expand Down Expand Up @@ -229,7 +231,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {

// TODO: How many iterations should we do?
while (_balance < _rewardAmount) {
_balance += _slash(_disputeId, 1, MAX_USERS_TO_CHECK, _result, _status);
_balance += _slash(_disputeId, MAX_USERS_TO_SLASH, maxUsersToCheck, _result, _status);
}

// Send the user the amount they won by participating in the dispute
Expand Down Expand Up @@ -350,6 +352,22 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
_approvedModules = _approvals[_user].values();
}

/// @inheritdoc IHorizonAccountingExtension
function setMaxUsersToCheck(uint128 _maxUsersToCheck) external {
ARBITRABLE.validateArbitrator(msg.sender);
_setMaxUsersToCheck(_maxUsersToCheck);
}

/**
* @notice Set the maximum number of users to check.
* @param _maxUsersToCheck The maximum number of users to check.
*/
function _setMaxUsersToCheck(uint128 _maxUsersToCheck) internal {
maxUsersToCheck = _maxUsersToCheck;

emit MaxUsersToCheckSet(_maxUsersToCheck);
}

/**
* @notice Slash the users that have pledged for a dispute.
* @param _disputeId The dispute id.
Expand Down
30 changes: 30 additions & 0 deletions src/interfaces/IHorizonAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {IBondEscalationModule} from
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {IHorizonStaking} from 'interfaces/external/IHorizonStaking.sol';

import {IArbitrable} from 'interfaces/IArbitrable.sol';

interface IHorizonAccountingExtension is IValidator {
/*///////////////////////////////////////////////////////////////
EVENTS
Expand Down Expand Up @@ -218,6 +220,18 @@ interface IHorizonAccountingExtension is IValidator {
*/
function MAX_VERIFIER_CUT() external view returns (uint32 _MAX_VERIFIER_CUT);

/**
* @notice The max number of users to slash
* @return _MAX_USERS_TO_SLASH The number of users to slash
*/
function MAX_USERS_TO_SLASH() external view returns (uint32 _MAX_USERS_TO_SLASH);

/**
* @notice The maximum users to check
* @return _maxUsersToCheck The maximum users to check
*/
function maxUsersToCheck() external view returns (uint128 _maxUsersToCheck);

/**
* @notice The total bonded tokens for a user
* @param _user The user address
Expand Down Expand Up @@ -383,4 +397,20 @@ interface IHorizonAccountingExtension is IValidator {
* @param _amount The amount of GRT to release
*/
function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external;

/**
* @notice Allows a anyone to slash a number of users for a dispute
* @dev After the established thawing period the losing pledgers can withdraw their stake from Horizon.
* Users should be slashed before that period ends to ensure that funds are available.
* @param _disputeId The ID of the dispute
* @param _usersToSlash The number of users to slash
* @param _maxUsersToCheck The maximum number of users to check before finishing the slashing
*/
function slash(bytes32 _disputeId, uint256 _usersToSlash, uint256 _maxUsersToCheck) external;

/**
* @notice Sets the maximum users to check
* @param _maxUsersToCheck The new value of max users to check
*/
function setMaxUsersToCheck(uint128 _maxUsersToCheck) external;
}
14 changes: 7 additions & 7 deletions test/integration/arbitrum/BondEscalation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ contract IntegrationBondEscalation is IntegrationBase {
// Stake GRT and create provisions
_stakeGRT();
_createProvisions();

// Create the request
_requestId = _createRequest();
// Propose the response
_responseId = _proposeResponse(_requestId);
// Dispute the response
_disputeId = _disputeResponse(_requestId, _responseId);
}

function test_PledgeForDispute() public {
Expand Down Expand Up @@ -156,13 +163,6 @@ contract IntegrationBondEscalation is IntegrationBase {
}

function test_InsufficientBondedTokens() public {
// Create the request
bytes32 _requestId = _createRequest();
// Propose the response
bytes32 _responseId = _proposeResponse(_requestId);
// Dispute the response
bytes32 _disputeId = _disputeResponse(_requestId, _responseId);

// Disputer tries to pledge for or against dispute after adding to their provision.
_stakeGRT();
_addToProvision(_disputer, disputeBondSize - 1);
Expand Down
11 changes: 10 additions & 1 deletion test/unit/Deploy.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
_ARBITRUM_SEPOLIA_EPOCH_MANAGER,
_ARBITRUM_SEPOLIA_GRAPH_TOKEN,
_ARBITRUM_SEPOLIA_HORIZON_STAKING,
_MAX_USERS_TO_CHECK,
_MIN_THAWING_PERIOD
} from 'script/Constants.sol';

Expand Down Expand Up @@ -81,8 +82,8 @@
public
givenTheGraphAccountsAreSetUp
{
uint256 _nonceEBORequestCreator = vm.getNonce(tx.origin) + deploy.OFFSET_EBO_REQUEST_CREATOR();

Check warning on line 85 in test/unit/Deploy.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Avoid to use tx.origin
address _precomputedEBORequestCreator = vm.computeCreateAddress(tx.origin, _nonceEBORequestCreator);

Check warning on line 86 in test/unit/Deploy.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Avoid to use tx.origin
vm.assume(_precomputedEBORequestCreator != _precomputedAddress);

deploy.mock_setPrecomputedAddress(_precomputedAddress);
Expand All @@ -93,9 +94,9 @@
}

function test_RunWhenPrecomputedAddressIsCorrect() public givenTheGraphAccountsAreSetUp {
uint256 _nonceBefore = vm.getNonce(tx.origin);

Check warning on line 97 in test/unit/Deploy.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Avoid to use tx.origin
deploy.run();
uint256 _nonceAfter = vm.getNonce(tx.origin);

Check warning on line 99 in test/unit/Deploy.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Avoid to use tx.origin

// it should deploy all contracts using a single EOA
assertEq(deploy.DEPLOYMENT_COUNT(), _nonceAfter - _nonceBefore);
Expand Down Expand Up @@ -137,13 +138,21 @@
// it should deploy `HorizonAccountingExtension` with correct args
address[] memory _authorizedCallers = _instantiateAuthorizedCallers();
HorizonAccountingExtension _horizonAccountingExtension = new HorizonAccountingExtension(
deploy.horizonStaking(), deploy.oracle(), deploy.graphToken(), _MIN_THAWING_PERIOD, _authorizedCallers
deploy.horizonStaking(),
deploy.oracle(),
deploy.graphToken(),
deploy.arbitrable(),
_MIN_THAWING_PERIOD,
_MAX_USERS_TO_CHECK,
_authorizedCallers
);
assertEq(address(deploy.horizonAccountingExtension()).code, address(_horizonAccountingExtension).code);
assertEq(address(deploy.horizonAccountingExtension().HORIZON_STAKING()), address(deploy.horizonStaking()));
assertEq(address(deploy.horizonAccountingExtension().ORACLE()), address(deploy.oracle()));
assertEq(address(deploy.horizonAccountingExtension().ARBITRABLE()), address(deploy.arbitrable()));
assertEq(address(deploy.horizonAccountingExtension().GRT()), address(deploy.graphToken()));
assertEq(deploy.horizonAccountingExtension().MIN_THAWING_PERIOD(), _MIN_THAWING_PERIOD);
assertEq(deploy.horizonAccountingExtension().maxUsersToCheck(), _MAX_USERS_TO_CHECK);
for (uint256 _i; _i < _authorizedCallers.length; ++_i) {
assertTrue(deploy.horizonAccountingExtension().authorizedCallers(_authorizedCallers[_i]));
}
Expand Down
38 changes: 2 additions & 36 deletions test/unit/HorizonAccountingExtension.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ contract HorizonAccountingExtensionForTest is HorizonAccountingExtension {
IHorizonStaking _horizonStaking,
IOracle _oracle,
IERC20 _grt,
IArbitrable _arbitrable,
uint64 _minThawingPeriod,
uint128 _maxUsersToCheck,
address[] memory _authorizedCallers
)
HorizonAccountingExtension(
Expand Down Expand Up @@ -337,42 +339,6 @@ contract HorizonAccountingExtension_Unit_Pledge is HorizonAccountingExtension_Un
horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount);
}

function test_insufficientTokens_thawing(
address _pledger,
uint256 _amount,
uint256 _tokensThawing,
uint256 _tokens
) public {
0xJabberwock marked this conversation as resolved.
Show resolved Hide resolved
vm.assume(_amount > 0);
vm.assume(_tokens > _amount);
vm.assume(_tokens > _tokensThawing);
vm.assume(_tokens - _tokensThawing < _amount);

_provisionData.tokens = _tokens;
_provisionData.tokensThawing = _tokensThawing;
_provisionData.thawingPeriod = MIN_THAWING_PERIOD;
_provisionData.maxVerifierCut = MAX_VERIFIER_CUT;

_mockAndExpect(address(oracle), abi.encodeCall(IOracle.disputeCreatedAt, (_mockDisputeId)), abi.encode(1));

_mockAndExpect(
address(oracle), abi.encodeCall(IOracle.allowedModule, (_mockRequestId, authorizedCaller)), abi.encode(true)
);

vm.mockCall(
address(horizonStaking),
abi.encodeWithSelector(horizonStaking.getProvision.selector, _pledger, horizonAccountingExtension),
abi.encode(_provisionData)
);

vm.expectRevert(
abi.encodeWithSelector(IHorizonAccountingExtension.HorizonAccountingExtension_InsufficientTokens.selector)
);

vm.prank(authorizedCaller);
horizonAccountingExtension.pledge(_pledger, mockRequest, mockDispute, grt, _amount);
}

function test_insufficientBondedTokens(
address _pledger,
uint128 _amount,
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.