Skip to content

Commit

Permalink
refactor: Rename and refactor the example vaults section
Browse files Browse the repository at this point in the history
  • Loading branch information
mgnfy-view committed Oct 30, 2024
1 parent a885457 commit 22da7e0
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 76 deletions.
76 changes: 0 additions & 76 deletions src/exampleHooks/PaymentSplitterVault.sol

This file was deleted.

26 changes: 26 additions & 0 deletions src/exampleVaults/script/DeployPaymentSplitterVault.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import { Script } from "forge-std/Script.sol";

import { PaymentSplitterVault } from "../vaults/PaymentSplitterVault.sol";

contract DeployPayStreams is Script {
address public stream;
address[] public recipients;
uint256[] public weights;

function run() external returns (address) {
stream = 0xfD3c782Ae7Ab6950409C65ba839349F5C0B32f19;
recipients.push(0xa15C94e0b133111878EA3256aBd5dF22E50B7240);
recipients.push(0x54D946760093fd5756c3EA4b9CCAE047c0ad4411);
weights.push(70);
weights.push(30);

vm.startBroadcast();
PaymentSplitterVault vault = new PaymentSplitterVault(stream, recipients, weights);
vm.stopBroadcast();

return address(vault);
}
}
145 changes: 145 additions & 0 deletions src/exampleVaults/vaults/PaymentSplitterVault.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import { IERC20 } from "@openzeppelin/token/ERC20/IERC20.sol";

import { SafeERC20 } from "@openzeppelin/token/ERC20/utils/SafeERC20.sol";

import { IPayStreams } from "../../interfaces/IPayStreams.sol";

import { BaseVault } from "../../utils/BaseVault.sol";

/**
* @title PaymentSplitterVault.
* @author mgnfy-view.
* @notice A payment splitter vault that splits any streamed payment among a
* list of recipients based on their assigned weights.
*/
contract PaymentSplitterVault is BaseVault {
using SafeERC20 for IERC20;

address private s_payStreams;
address[] private s_recipients;
uint256[] private s_weights;
uint256 private s_totalWeight;

event PaymentSplit(address[] indexed recipients, uint256[] indexed amounts);
event RecipientAndWeightsListUpdated(address[] indexed recipients, uint256[] indexed weights);

error PaymentSplitterVault__ArrayLengthMismatch();
error PaymentSplitterVault__NotPayStream();

modifier onlyPayStreams() {
if (msg.sender != address(s_payStreams)) revert PaymentSplitterVault__NotPayStream();
_;
}

/**
* @notice Initializes the vault.
* @param _payStreams The address of the payStreams contract.
* @param _recipients A list of recipients of the streamed amount.
* @param _weights Assigned weight to each recipient in the list.
*/
constructor(address _payStreams, address[] memory _recipients, uint256[] memory _weights) {
if (_recipients.length != _weights.length) revert PaymentSplitterVault__ArrayLengthMismatch();

s_payStreams = _payStreams;
s_recipients = _recipients;
s_weights = _weights;

uint256 totalWeight;
for (uint256 i; i < _weights.length; ++i) {
totalWeight += _weights[i];
}
s_totalWeight = totalWeight;
}

/**
* @notice Once funds have been received by this vault, this function is invoked by the
* payStreams contract to split the streamed funds among multiple recipients based on their weight.
* @param _streamHash The hash of the stream.
* @param _amount The amount along with the fee.
* @param _feeAmount The fee collected from the streamed amount.
*/
function afterFundsCollected(
bytes32 _streamHash,
uint256 _amount,
uint256 _feeAmount
)
external
override
onlyPayStreams
{
address token = IPayStreams(s_payStreams).getStreamData(_streamHash).token;
address[] memory recipients = s_recipients;
uint256[] memory weights = s_weights;
uint256 numberOfRecipients = recipients.length;
uint256 totalWeight = s_totalWeight;
uint256[] memory amounts = new uint256[](numberOfRecipients);

for (uint256 i; i < numberOfRecipients; ++i) {
uint256 amount = ((_amount - _feeAmount) * weights[i]) / totalWeight;
amounts[i] = amount;
IERC20(token).safeTransfer(recipients[i], amount);
}

emit PaymentSplit(recipients, amounts);
}

/**
* @notice Allows the owner to update the recipient and the weights list.
* @param _recipients The new list of recipients.
* @param _weights The weights assigned to each recipient.
*/
function updateRecipientAndWeightsList(
address[] memory _recipients,
uint256[] memory _weights
)
external
onlyOwner
{
if (_recipients.length != _weights.length) revert PaymentSplitterVault__ArrayLengthMismatch();
s_recipients = _recipients;
s_weights = _weights;

uint256 totalWeight;
for (uint256 i; i < _weights.length; ++i) {
totalWeight += _weights[i];
}
s_totalWeight = totalWeight;

emit RecipientAndWeightsListUpdated(_recipients, _weights);
}

/**
* @notice Gets the payStreams contract address.
* @return The payStreams contract address.
*/
function getPayStreams() external view returns (address) {
return s_payStreams;
}

/**
* @notice Gets the recipients list.
* @return The recipients list.
*/
function getRecipients() external view returns (address[] memory) {
return s_recipients;
}

/**
* @notice Gets the weights list.
* @return The weights list.
*/
function getWeights() external view returns (uint256[] memory) {
return s_weights;
}

/**
* @notice Gets the total weight based on the weights list.
* @return The total weight.
*/
function getTotalWeight() external view returns (uint256) {
return s_totalWeight;
}
}

0 comments on commit 22da7e0

Please sign in to comment.