Skip to content

Commit

Permalink
fix(RNSCommission)
Browse files Browse the repository at this point in the history
  • Loading branch information
tringuyenskymavis committed Jun 6, 2024
1 parent cad6124 commit e2d4138
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 55 deletions.
72 changes: 22 additions & 50 deletions src/RNSCommission.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import { RONTransferHelper } from "./libraries/transfers/RONTransferHelper.sol";
contract RNSCommission is Initializable, AccessControlEnumerable, INSCommission {
/// @dev Constant representing the maximum percentage value (100%).
uint256 public constant MAX_PERCENTAGE = 100_00;
/// @dev Role for accounts that can set commissions infomation and grant or revoke `SENDER_ROLE`.
bytes32 public constant COMMISSION_SETTER_ROLE = keccak256("COMMISSION_SETTER_ROLE");
/// @dev Role for accounts that can send RON for this contract.
bytes32 public constant SENDER_ROLE = keccak256("SENDER_ROLE");

/// @dev Gap for upgradability.
uint256[50] private ____gap;

/// @dev Array of `Commission` structs that store commissions infomation.
Commission[] internal _commissionInfos;

constructor() {
Expand All @@ -27,25 +25,17 @@ contract RNSCommission is Initializable, AccessControlEnumerable, INSCommission
_fallback();
}

function initialize(
address admin,
address[] calldata commissionSetters,
Commission[] calldata commissionInfos,
address[] calldata allowedSenders
) external initializer {
function initialize(address admin, Commission[] calldata commissionInfos, address[] calldata allowedSenders)
external
initializer
{
_setupRole(DEFAULT_ADMIN_ROLE, admin);

uint256 length = commissionSetters.length;
uint256 length = allowedSenders.length;
for (uint256 i; i < length; ++i) {
_setupRole(COMMISSION_SETTER_ROLE, commissionSetters[i]);
}

uint256 sendersLength = allowedSenders.length;
for (uint256 i; i < sendersLength; ++i) {
_setupRole(SENDER_ROLE, allowedSenders[i]);
}

_setRoleAdmin(SENDER_ROLE, COMMISSION_SETTER_ROLE);
_setCommissions(commissionInfos);
}

Expand All @@ -55,64 +45,46 @@ contract RNSCommission is Initializable, AccessControlEnumerable, INSCommission
}

/// @inheritdoc INSCommission
function setCommissions(Commission[] calldata commissionInfos) external onlyRole(COMMISSION_SETTER_ROLE) {
function setCommissions(Commission[] calldata commissionInfos) external onlyRole(DEFAULT_ADMIN_ROLE) {
_setCommissions(commissionInfos);
}

/// @inheritdoc INSCommission
function setCommissionInfo(uint256 commissionIdx, address payable newRecipient, string calldata newName)
external
onlyRole(COMMISSION_SETTER_ROLE)
onlyRole(DEFAULT_ADMIN_ROLE)
{
if (commissionIdx > _commissionInfos.length - 1) {
revert InvalidArrayLength();
}
if (commissionIdx >= _commissionInfos.length) revert InvalidArrayLength();

_commissionInfos[commissionIdx].recipient = newRecipient;
_commissionInfos[commissionIdx].name = newName;
emit CommissionInfoUpdated(msg.sender, commissionIdx, newRecipient, newName);
}

/**
* @dev Helper method to calculate allocations.
* @dev Helper method to allocate commission and take fee into recipient address.
*/
function _calcAllocations(uint256 totalAmount) internal view returns (Allocation[] memory allocs) {
if (totalAmount == 0) {
revert InvalidAmountOfRON();
}
uint256 length = _commissionInfos.length;
function _allocateCommissionAndTransferToRecipient(uint256 ronAmount) internal {
if (ronAmount == 0) revert InvalidAmountOfRON();

allocs = new Allocation[](length);
uint256 length = _commissionInfos.length;
if (length == 0) revert InvalidArrayLength();

uint256 lastIdx = length - 1;
uint256 sumValue;

for (uint256 i; i < lastIdx; ++i) {
allocs[i] = Allocation({
recipient: _commissionInfos[i].recipient,
value: _computePercentage(totalAmount, _commissionInfos[i].ratio)
});
sumValue += allocs[i].value;
}
uint256 commissionAmount = _computePercentage(ronAmount, _commissionInfos[i].ratio);
sumValue += commissionAmount;

// This code replaces value of the last recipient.
if (sumValue < totalAmount) {
allocs[lastIdx] = Allocation({ recipient: _commissionInfos[lastIdx].recipient, value: totalAmount - sumValue });
RONTransferHelper.safeTransfer(_commissionInfos[i].recipient, commissionAmount);
emit Transfer(_commissionInfos[i].recipient, commissionAmount);
}
}

/**
* @dev Helper method to allocate commission and take fee into recipient address.
*/
function _allocateCommissionAndTransferToRecipient(uint256 ronAmount) internal {
INSCommission.Allocation[] memory allocs = _calcAllocations(ronAmount);
uint256 length = allocs.length;

for (uint256 i; i < length; ++i) {
uint256 value = allocs[i].value;
address payable recipient = allocs[i].recipient;

RONTransferHelper.safeTransfer(recipient, value);
// This code send the remaining RON to the last recipient.
if (sumValue < ronAmount) {
RONTransferHelper.safeTransfer(_commissionInfos[lastIdx].recipient, ronAmount - sumValue);
emit Transfer(_commissionInfos[lastIdx].recipient, ronAmount - sumValue);
}
}

Expand Down
17 changes: 12 additions & 5 deletions src/interfaces/INSCommission.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ interface INSCommission {
string name; // Commission's name
}

struct Allocation {
address payable recipient;
uint256 value;
}

/// @dev Emitted when all the commission info is updated.
event CommissionsUpdated(address indexed updatedBy, Commission[] commissionInfos);
/// @dev Emitted when specific commission info is updated.
event CommissionInfoUpdated(
address indexed updatedBy, uint256 indexed commissionIdx, address payable newRecipient, string newName
);
/// @dev Emiited when transfer RON to commission's recipient.
event Transfer(address indexed recipient, uint256 commissionAmount);

/// @dev Revert when index is out of range
error InvalidArrayLength();
Expand All @@ -27,6 +24,16 @@ interface INSCommission {
/// @dev Revert when amount of RON is invalid
error InvalidAmountOfRON();

/**
* @dev Maximum commission percentage.
*/
function MAX_PERCENTAGE() external pure returns (uint256);

/**
* @dev Returns the sender role.
*/
function SENDER_ROLE() external pure returns (bytes32);

/**
* @dev Returns comissions information.
*/
Expand Down

0 comments on commit e2d4138

Please sign in to comment.