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

feat: integrate HorizonAccountingExtension #37

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
46 changes: 32 additions & 14 deletions src/contracts/HorizonAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,6 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
_;
}

/// @inheritdoc IHorizonAccountingExtension
function approvedModules(address _user) external view returns (address[] memory _approvedModules) {
_approvedModules = _approvals[_user].values();
}

/// @inheritdoc IHorizonAccountingExtension
function approveModule(address _module) external {
_approvals[msg.sender].add(_module);
Expand All @@ -135,6 +130,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
address _pledger,
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
IERC20, /* _token */
uint256 _amount
) external onlyAuthorizedCaller {
bytes32 _requestId = _getId(_request);
Expand All @@ -155,6 +151,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
function onSettleBondEscalation(
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
IERC20, /* _token */
uint256 _amountPerPledger,
uint256 _winningPledgersLength
) external onlyAuthorizedCaller {
Expand All @@ -176,7 +173,7 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
escalationResults[_disputeId] = EscalationResult({
requestId: _requestId,
amountPerPledger: _amountPerPledger,
bondSize: _bondEscalationModule.decodeRequestData(_request.requestModuleData).bondSize,
bondSize: _bondEscalationModule.decodeRequestData(_request.disputeModuleData).bondSize,
0xShaito marked this conversation as resolved.
Show resolved Hide resolved
bondEscalationModule: _bondEscalationModule
});

Expand Down Expand Up @@ -218,32 +215,32 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
? _result.bondEscalationModule.pledgesForDispute(_requestId, _pledger)
: _result.bondEscalationModule.pledgesAgainstDispute(_requestId, _pledger);

// Release the winning pledges to the user
_pledgeAmount = _result.bondSize * _numberOfPledges;

_claimAmount = _amountPerPledger * _numberOfPledges;
_rewardAmount = _claimAmount - _pledgeAmount;

// Check the balance in the contract
// If not enough balance, slash some users to get enough balance
uint256 _balance = GRT.balanceOf(address(this));
uint256 _balance = GRT.balanceOf(address(this)); // TODO: What if the balance is enough by means other than slashing?

// TODO: How many iterations should we do?
while (_balance < _claimAmount) {
while (_balance < _rewardAmount) {
0xShaito marked this conversation as resolved.
Show resolved Hide resolved
_balance += _slash(_disputeId, 1, MAX_USERS_TO_CHECK, _result, _status);
}

_rewardAmount = _claimAmount - _pledgeAmount;

// Send the user the amount they won by participating in the dispute
GRT.safeTransfer(_pledger, _rewardAmount);
}

// Release the winning pledges to the user
_unbond(_pledger, _pledgeAmount);

pledgerClaimed[_requestId][_pledger] = true;

pledges[_disputeId] -= _claimAmount;

// TODO: Delete _pledgers[_disputeId] if pledges[_disputeId] == 0

emit EscalationRewardClaimed({
_requestId: _requestId,
_disputeId: _disputeId,
Expand All @@ -253,11 +250,13 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
});
}

// TODO: Remove
/// @inheritdoc IHorizonAccountingExtension
function releasePledge(
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
address _pledger,
IERC20, /* _token */
uint256 _amount
) external onlyAuthorizedCaller {
bytes32 _requestId = _getId(_request);
Expand Down Expand Up @@ -368,6 +367,22 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {
_slash(_disputeId, _usersToSlash, _maxUsersToCheck, _result, _status);
}

/// @inheritdoc IHorizonAccountingExtension
function getEscalationResult(bytes32 _disputeId) external view returns (EscalationResult memory _escalationResult) {
_escalationResult = escalationResults[_disputeId];
}

/// @inheritdoc IHorizonAccountingExtension
function approvedModules(address _user) external view returns (address[] memory _approvedModules) {
_approvedModules = _approvals[_user].values();
}

// TODO: Remove if unwanted
/// @inheritdoc IHorizonAccountingExtension
function getPledgers(bytes32 _disputeId) external view returns (address[] memory __pledgers) {
__pledgers = _pledgers[_disputeId].values();
}

/**
* @notice Slash the users that have pledged for a dispute.
* @param _disputeId The dispute id.
Expand All @@ -393,18 +408,21 @@ contract HorizonAccountingExtension is Validator, IHorizonAccountingExtension {

_maxUsersToCheck = _maxUsersToCheck > _length ? _length : _maxUsersToCheck;

for (uint256 _i; _i < _maxUsersToCheck && _slashedUsers < _usersToSlash; _i++) {
for (uint256 _i; _i < _maxUsersToCheck && _slashedUsers < _usersToSlash; ++_i) {
_user = _users.at(0);

// Check if the user is actually slashable
_slashAmount = _calculateSlashAmount(_user, _result, _status);
if (_slashAmount > 0) {
// Slash the user
HORIZON_STAKING.slash(_user, _slashAmount, _slashAmount, address(this));
// TODO: What if `MIN_THAWING_PERIOD` has passed, all provision tokens have been thawed and slashing is skipped or reverts (bricking `claimEscalationReward()`)?

// TODO: Unbond slashed pledgers

_slashedAmount += _slashAmount;

_slashedUsers++;
++_slashedUsers;
}

// Remove the user from the list of users
Expand Down
62 changes: 41 additions & 21 deletions src/interfaces/IHorizonAccountingExtension.sol
Original file line number Diff line number Diff line change
Expand Up @@ -227,22 +227,22 @@ interface IHorizonAccountingExtension is IValidator {
/**
* @notice The bound amount of tokens for a user in a request
* @param _user The user address
* @param _requestId The request Id
* @param _requestId The ID of the request
* @return _amount The amount of tokens bonded
*/
function bondedForRequest(address _user, bytes32 _requestId) external view returns (uint256 _amount);

/**
* @notice The total pledged tokens for a user
* @param _disputeId The dispute Id
* @param _disputeId The ID of the dispute
* @return _amount The total pledged tokens for a user
*/
function pledges(bytes32 _disputeId) external view returns (uint256 _amount);

/**
* @notice The escalation result of a request
* @param _disputeId The dispute Id
* @return _requestId The request Id
* @notice The escalation result of a dispute
* @param _disputeId The ID of the dispute
* @return _requestId The ID of the request
* @return _amountPerPledger The amount of token paid to each of the winning pledgers
* @return _bondSize The size of the bond required for bond escalation
* @return _bondEscalationModule The address of the bond escalation module that was used
Expand All @@ -257,14 +257,29 @@ interface IHorizonAccountingExtension is IValidator {
IBondEscalationModule _bondEscalationModule
);

/**
* @notice The escalation result of a dispute
* @param _disputeId The ID of the dispute
* @return _escalationResult The escalation result
*/
function getEscalationResult(bytes32 _disputeId) external view returns (EscalationResult memory _escalationResult);

/**
* @notice The claim status of a user for a pledge
* @param _requestId The request Id
* @param _requestId The ID of the request
* @param _pledger The user address
* @return _claimed True if the user claimed their pledge
*/
function pledgerClaimed(bytes32 _requestId, address _pledger) external view returns (bool _claimed);

/**
* @notice Checks whether an address is an authorized caller
*
* @param _caller The address to check
* @return _authorized True if the address is authorized, false otherwise
*/
function authorizedCallers(address _caller) external returns (bool _authorized);

/**
* @notice Returns the approved modules for bonding tokens
* @param _user The address of the user
Expand All @@ -273,12 +288,11 @@ interface IHorizonAccountingExtension is IValidator {
function approvedModules(address _user) external view returns (address[] memory _approvedModules);

/**
* @notice Checks whether an address is an authorized caller.
*
* @param _caller The address to check
* @return _authorized True if the address is authorized, false otherwise
* @notice Returns the pledgers for a dispute
* @param _disputeId The ID of the dispute
* @return _pledgers The pledgers for the dispute
*/
function authorizedCallers(address _caller) external returns (bool _authorized);
function getPledgers(bytes32 _disputeId) external view returns (address[] memory _pledgers);

/*///////////////////////////////////////////////////////////////
LOGIC
Expand All @@ -297,16 +311,18 @@ interface IHorizonAccountingExtension is IValidator {
function revokeModule(address _module) external;

/**
* @notice Pledges the given amount of token to the provided dispute id of the provided request id
* @notice Pledges the given amount of token to the provided dispute ID of the provided request ID
* @param _pledger Address of the pledger
* @param _request The bond-escalated request
* @param _dispute The bond-escalated dispute
* @param _amount Amount of token to pledge
* @param _token Address of the token being paid as a reward for winning the bond escalation
* @param _amount Amount of GRT to pledge
*/
function pledge(
address _pledger,
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
IERC20 _token,
uint256 _amount
) external;

Expand All @@ -315,12 +331,14 @@ interface IHorizonAccountingExtension is IValidator {
* @notice Updates the accounting of the given dispute to reflect the result of the bond escalation
* @param _request The bond-escalated request
* @param _dispute The bond-escalated dispute
* @param _token Address of the token being paid as a reward for winning the bond escalation
* @param _amountPerPledger Amount of GRT to be rewarded to each of the winning pledgers
* @param _winningPledgersLength Amount of pledges that won the dispute
*/
function onSettleBondEscalation(
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
IERC20 _token,
uint256 _amountPerPledger,
uint256 _winningPledgersLength
) external;
Expand All @@ -337,50 +355,52 @@ interface IHorizonAccountingExtension is IValidator {
* @param _request The bond-escalated request
* @param _dispute The bond-escalated dispute
* @param _pledger Address of the pledger
* @param _token Address of the token to be released
* @param _amount Amount of GRT to be released to the pledger
*/
function releasePledge(
IOracle.Request calldata _request,
IOracle.Dispute calldata _dispute,
address _pledger,
IERC20 _token,
uint256 _amount
) external;

/**
* @notice Allows a allowed module to transfer bonded tokens from one user to another
* @param _requestId The id of the request handling the user's tokens
* @param _requestId The ID of the request handling the user's tokens
* @param _payer The address of the user paying the tokens
* @param _receiver The address of the user receiving the tokens
* @param _token The address of the token being transferred
* @param _amount The amount of `_token` being transferred
* @param _amount The amount of GRT being transferred
*/
function pay(bytes32 _requestId, address _payer, address _receiver, IERC20 _token, uint256 _amount) external;

/**
* @notice Allows an allowed module to bond a user's tokens for a request
* @param _bonder The address of the user to bond tokens for
* @param _requestId The id of the request the user is bonding for
* @param _requestId The ID of the request the user is bonding for
* @param _token The address of the token being bonded
* @param _amount The amount of `_token` to bond
* @param _amount The amount of GRT to bond
*/
function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external;

/**
* @notice Allows a valid module to bond a user's tokens for a request
* @param _bonder The address of the user to bond tokens for
* @param _requestId The id of the request the user is bonding for
* @param _requestId The ID of the request the user is bonding for
* @param _token The address of the token being bonded
* @param _amount The amount of `_token` to bond
* @param _amount The amount of GRT to bond
* @param _sender The address starting the propose call on the Oracle
*/
function bond(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount, address _sender) external;

/**
* @notice Allows a valid module to release a user's tokens
* @param _bonder The address of the user to release tokens for
* @param _requestId The id of the request where the tokens were bonded
* @param _requestId The ID of the request where the tokens were bonded
* @param _token The address of the token being released
* @param _amount The amount of `_token` to release
* @param _amount The amount of GRT to release
*/
function release(address _bonder, bytes32 _requestId, IERC20 _token, uint256 _amount) external;
}
Loading
Loading