-
Notifications
You must be signed in to change notification settings - Fork 8
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
335 referral system #197
base: main
Are you sure you want to change the base?
335 referral system #197
Changes from 89 commits
ed6d77d
8ad8fda
25d5f65
a71195c
1683046
7407a52
d083d9c
b630bc5
f3bfa51
d72be64
fe78b13
4e3e1c6
2265b07
e5ae868
035a392
338c460
f52e7e5
5f4aab5
f9a6de8
14c6fee
d8d6f0c
68e8c23
b37c9c7
6ca051f
e02ba9d
6133da9
cc3e7ed
392fa20
7ed97d8
cb39a5b
56d642f
4cab0d9
a26caaf
7a4ba1c
176369d
a8a243a
ef36da3
fda6026
d5291d9
754725e
ecefa0c
a7cf324
1110ae3
882461b
2473716
88049a8
8015bb8
dd0d1a7
21543e7
1fe877b
95ce758
7494ba1
6906e6f
3b36de5
c4bb785
f805f95
9330f92
d499ac5
04ad7a5
0f95e33
02de40f
5c1d36c
de4a60d
6a68d11
064ff85
5cee3ca
d2adcbd
7d6a409
b750fbf
0b5a479
dca9904
688858a
30b3254
ba62899
f21c3b2
e1c5143
8805587
a74368d
a3e49af
4d60193
8263d23
6c2113c
fd2022c
7f9bd58
31010fc
05a458c
7f94981
f25d1b5
f4d13f0
5fed205
118fa86
8f90926
7f84e7a
cf3b865
0de07fc
be86269
fcd1153
797bd99
ba0c363
51bd676
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,7 +73,7 @@ contract TalentLayerEscrow is | |
* @param sender The party paying the escrow amount | ||
* @param receiver The intended receiver of the escrow amount | ||
* @param token The token used for the transaction | ||
* @param amount The amount of the transaction EXCLUDING FEES | ||
* @param amount The amount of the transaction EXCLUDING FEES (will diminish after each release payment) | ||
* @param releasedAmount The amount of the transaction that has been released to the receiver EXCLUDING FEES | ||
* @param serviceId The ID of the associated service | ||
* @param proposalId The id of the validated proposal | ||
|
@@ -88,6 +88,9 @@ contract TalentLayerEscrow is | |
* @param lastInteraction Last interaction for the dispute procedure. | ||
* @param arbitratorExtraData Extra data to set up the arbitration. | ||
* @param arbitrationFeeTimeout timeout for parties to pay the arbitration fee | ||
* @param referrerId the id of the optional referrer | ||
* @param referralAmount the optional lump sum optional amount to be sent to the referrer | ||
* @param totalAmount The amount of the transaction EXCLUDING FEES (fixed, will not vary) | ||
*/ | ||
struct Transaction { | ||
uint256 id; | ||
|
@@ -109,6 +112,9 @@ contract TalentLayerEscrow is | |
uint256 lastInteraction; | ||
bytes arbitratorExtraData; | ||
uint256 arbitrationFeeTimeout; | ||
uint256 referrerId; | ||
uint256 referralAmount; | ||
uint256 totalAmount; | ||
} | ||
|
||
// =========================== Events ============================== | ||
|
@@ -149,6 +155,14 @@ contract TalentLayerEscrow is | |
*/ | ||
event FeesClaimed(uint256 _platformId, address indexed _token, uint256 _amount); | ||
|
||
/** | ||
* @notice Emitted after a referrer withdraws its balance | ||
* @param _referrerId The TalentLayerID to which the balance is transferred. | ||
* @param _token The address of the token used for the payment. | ||
* @param _amount The amount transferred. | ||
*/ | ||
event ReferralAmountClaimed(uint256 _referrerId, address indexed _token, uint256 _amount); | ||
|
||
/** | ||
* @notice Emitted after an origin service fee is released to a platform's balance | ||
* @param _platformId The platform ID. | ||
|
@@ -177,6 +191,20 @@ contract TalentLayerEscrow is | |
uint256 _amount | ||
); | ||
|
||
/** | ||
* @notice Emitted after part of a referral amount is released | ||
* @param _referrerId The id of the referrer. | ||
* @param _serviceId The related service ID. | ||
* @param _token The address of the token used for the payment. | ||
* @param _amount The amount released. | ||
*/ | ||
event ReferralAmountReleased( | ||
uint256 indexed _referrerId, | ||
uint256 _serviceId, | ||
address indexed _token, | ||
uint256 _amount | ||
); | ||
|
||
/** | ||
* @notice Emitted when a party has to pay a fee for the dispute or would otherwise be considered as losing. | ||
* @param _transactionId The id of the transaction. | ||
|
@@ -320,6 +348,14 @@ contract TalentLayerEscrow is | |
*/ | ||
CountersUpgradeable.Counter private nextTransactionId; | ||
|
||
/** | ||
* @notice Mapping from referrerId to Token address to Token Balance | ||
* Represents the amount of ETH or token present on this contract which | ||
* belongs to a referrer and can be withdrawn. | ||
* @dev address(0) is reserved to ETH balance | ||
*/ | ||
mapping(uint256 => mapping(address => uint256)) private referrerIdToTokenToBalance; | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
constructor() { | ||
_disableInitializers(); | ||
|
@@ -368,7 +404,7 @@ contract TalentLayerEscrow is | |
|
||
/** | ||
* @dev Only the owner of the platform ID or the owner can execute this function | ||
* @param _token Token address ("0" for ETH) | ||
* @param _token Token address (address(0) for ETH) | ||
* @return balance The balance of the platform or the protocol | ||
*/ | ||
function getClaimableFeeBalance(address _token) external view returns (uint256 balance) { | ||
|
@@ -382,6 +418,15 @@ contract TalentLayerEscrow is | |
return platformIdToTokenToBalance[platformId][_token]; | ||
} | ||
|
||
/** | ||
* @param _token Token address (address(0) for ETH) | ||
* @return balance The balance of the referrer | ||
*/ | ||
function getClaimableReferralBalance(address _token) external view returns (uint256 balance) { | ||
uint256 referrerId = talentLayerIdContract.ids(_msgSender()); | ||
return referrerIdToTokenToBalance[referrerId][_token]; | ||
} | ||
|
||
/** | ||
* @notice Called to get the details of a transaction | ||
* @dev Only the transaction sender or receiver can call this function | ||
|
@@ -442,7 +487,7 @@ contract TalentLayerEscrow is | |
* @param _serviceId Id of the service that the sender created and the proposal was made for. | ||
* @param _proposalId Id of the proposal that the transaction validates. | ||
* @param _metaEvidence Link to the meta-evidence. | ||
* @param _originDataUri dataURI of the validated proposal | ||
* @param _originDataUri dataURI of the validated proposal. | ||
*/ | ||
function createTransaction( | ||
uint256 _serviceId, | ||
|
@@ -463,13 +508,16 @@ contract TalentLayerEscrow is | |
? talentLayerPlatformIdContract.getPlatform(proposal.platformId) | ||
: originServiceCreationPlatform; | ||
|
||
uint256 referralAmount = proposal.referrerId == 0 ? 0 : service.referralAmount; | ||
|
||
uint256 transactionAmount = _calculateTotalWithFees( | ||
proposal.rateAmount, | ||
originServiceCreationPlatform.originServiceFeeRate, | ||
originProposalCreationPlatform.originValidatedProposalFeeRate | ||
originProposalCreationPlatform.originValidatedProposalFeeRate, | ||
referralAmount | ||
); | ||
|
||
if (proposal.rateToken == address(0)) { | ||
if (service.rateToken == address(0)) { | ||
require(msg.value == transactionAmount, "Non-matching funds"); | ||
} else { | ||
require(msg.value == 0, "Non-matching funds"); | ||
|
@@ -491,7 +539,8 @@ contract TalentLayerEscrow is | |
id: transactionId, | ||
sender: sender, | ||
receiver: receiver, | ||
token: proposal.rateToken, | ||
token: service.rateToken, | ||
totalAmount: proposal.rateAmount, | ||
amount: proposal.rateAmount, | ||
releasedAmount: 0, | ||
serviceId: _serviceId, | ||
|
@@ -506,15 +555,17 @@ contract TalentLayerEscrow is | |
status: Status.NoDispute, | ||
arbitrator: originServiceCreationPlatform.arbitrator, | ||
arbitratorExtraData: originServiceCreationPlatform.arbitratorExtraData, | ||
arbitrationFeeTimeout: originServiceCreationPlatform.arbitrationFeeTimeout | ||
arbitrationFeeTimeout: originServiceCreationPlatform.arbitrationFeeTimeout, | ||
referrerId: proposal.referrerId, | ||
referralAmount: service.referralAmount | ||
}); | ||
|
||
nextTransactionId.increment(); | ||
|
||
talentLayerServiceContract.afterDeposit(_serviceId, _proposalId, transactionId); | ||
|
||
if (proposal.rateToken != address(0)) { | ||
IERC20Upgradeable(proposal.rateToken).safeTransferFrom(sender, address(this), transactionAmount); | ||
if (service.rateToken != address(0)) { | ||
IERC20Upgradeable(service.rateToken).safeTransferFrom(sender, address(this), transactionAmount); | ||
} | ||
|
||
_afterCreateTransaction(service.ownerId, proposal.ownerId, transactionId, _metaEvidence); | ||
|
@@ -525,7 +576,7 @@ contract TalentLayerEscrow is | |
/** | ||
* @notice Allows the sender to release locked-in escrow value to the intended recipient. | ||
* The amount released must not include the fees. | ||
* @param _profileId The TalentLayer ID of the user | ||
* @param _profileId The TalentLayer ID of the user. | ||
* @param _transactionId Id of the transaction to release escrow value for. | ||
* @param _amount Value to be released without fees. Should not be more than amount locked in. | ||
*/ | ||
|
@@ -546,7 +597,7 @@ contract TalentLayerEscrow is | |
/** | ||
* @notice Allows the intended receiver to return locked-in escrow value back to the sender. | ||
* The amount reimbursed must not include the fees. | ||
* @param _profileId The TalentLayer ID of the user | ||
* @param _profileId The TalentLayer ID of the user. | ||
* @param _transactionId Id of the transaction to reimburse escrow value for. | ||
* @param _amount Value to be reimbursed without fees. Should not be more than amount locked in. | ||
*/ | ||
|
@@ -729,6 +780,28 @@ contract TalentLayerEscrow is | |
emit FeesClaimed(_platformId, _tokenAddress, amount); | ||
} | ||
|
||
// =========================== Referrer functions ============================== | ||
|
||
/** | ||
* @notice Allows a referrer to claim its tokens & / or ETH balance. | ||
* @param _referrerId The ID of the referrer claiming the balance. | ||
* @param _tokenAddress The address of the Token contract (address(0) if balance in ETH). | ||
* @dev Emits a BalanceTransferred & a ReferralAmountClaimed events | ||
*/ | ||
function claimReferralBalance(uint256 _referrerId, address _tokenAddress) external whenNotPaused { | ||
address payable recipient; | ||
|
||
talentLayerIdContract.isValid(_referrerId); | ||
recipient = payable(talentLayerIdContract.ownerOf(_referrerId)); | ||
|
||
uint256 amount = referrerIdToTokenToBalance[_referrerId][_tokenAddress]; | ||
require(amount > 0, "nothing to claim"); | ||
referrerIdToTokenToBalance[_referrerId][_tokenAddress] = 0; | ||
_safeTransferBalance(recipient, _tokenAddress, amount); | ||
|
||
emit ReferralAmountClaimed(_referrerId, _tokenAddress, amount); | ||
} | ||
|
||
// =========================== Arbitrator functions ============================== | ||
|
||
/** | ||
|
@@ -841,10 +914,10 @@ contract TalentLayerEscrow is | |
// =========================== Private functions ============================== | ||
|
||
/** | ||
* @notice Emits the events related to the creation of a transaction. | ||
* @notice Emits the events related to the creation of a transaction | ||
* @param _senderId The TL ID of the sender | ||
* @param _receiverId The TL ID of the receiver | ||
* @param _transactionId The ID of the transavtion | ||
* @param _transactionId The ID of the transaction | ||
* @param _metaEvidence The meta evidence of the transaction | ||
*/ | ||
function _afterCreateTransaction( | ||
|
@@ -896,12 +969,21 @@ contract TalentLayerEscrow is | |
*/ | ||
function _reimburse(uint256 _transactionId, uint256 _amount) private { | ||
Transaction storage transaction = transactions[_transactionId]; | ||
uint256 totalReleaseAmount = _calculateTotalWithFees( | ||
|
||
// If no referrerId (=0), the referralAmount will always be 0 | ||
// @dev: Legacy transactions will have a totalAmount of 0; need to check for that | ||
// @dev: This check should be removed in a future upgrade, when all legacy transactions will be completed | ||
uint256 reimbursedReferralAmount = transaction.totalAmount != 0 | ||
? (_amount * transaction.referralAmount) / (transaction.totalAmount) | ||
: 0; | ||
|
||
uint256 totalReimburseAmount = _calculateTotalWithFees( | ||
_amount, | ||
transaction.originServiceFeeRate, | ||
transaction.originValidatedProposalFeeRate | ||
transaction.originValidatedProposalFeeRate, | ||
reimbursedReferralAmount | ||
); | ||
_safeTransferBalance(payable(transaction.sender), transaction.token, totalReleaseAmount); | ||
_safeTransferBalance(payable(transaction.sender), transaction.token, totalReimburseAmount); | ||
|
||
_afterPayment(_transactionId, PaymentType.Reimburse, _amount); | ||
} | ||
|
@@ -932,12 +1014,25 @@ contract TalentLayerEscrow is | |
transaction.token | ||
] += originValidatedProposalFeeRate; | ||
|
||
if (transaction.referrerId != 0 && transaction.referralAmount != 0) { | ||
0xRomain marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint256 releasedReferralAmount = (_releaseAmount * transaction.referralAmount) / (transaction.totalAmount); | ||
referrerIdToTokenToBalance[transaction.referrerId][transaction.token] = releasedReferralAmount; | ||
|
||
emit ReferralAmountReleased( | ||
transaction.referrerId, | ||
transaction.serviceId, | ||
transaction.token, | ||
releasedReferralAmount | ||
); | ||
} | ||
|
||
emit OriginServiceFeeRateReleased( | ||
originServiceCreationPlatformId, | ||
transaction.serviceId, | ||
transaction.token, | ||
originServiceFeeRate | ||
); | ||
|
||
emit OriginValidatedProposalFeeRateReleased( | ||
originValidatedProposalPlatformId, | ||
transaction.serviceId, | ||
|
@@ -947,7 +1042,7 @@ contract TalentLayerEscrow is | |
} | ||
|
||
/** | ||
* @notice Used to validate a realease or a reimburse payment | ||
* @notice Used to validate a release or a reimburse payment | ||
* @param _transactionId The transaction linked to the payment | ||
* @param _paymentType The type of payment to validate | ||
* @param _profileId The profileId of the msgSender | ||
|
@@ -1007,18 +1102,21 @@ contract TalentLayerEscrow is | |
* @param _amount The core escrow amount | ||
* @param _originServiceFeeRate the %fee (per ten thousands) asked by the platform for each service created on the platform | ||
* @param _originValidatedProposalFeeRate the %fee (per ten thousands) asked by the platform for each validates service on the platform | ||
* @param _referralAmount the lump sum optional amount to be sent to the referrer, if any | ||
* @return totalEscrowAmount The total amount to be paid by the buyer (including all fees + escrow) The amount to transfer | ||
*/ | ||
function _calculateTotalWithFees( | ||
uint256 _amount, | ||
uint16 _originServiceFeeRate, | ||
uint16 _originValidatedProposalFeeRate | ||
uint16 _originValidatedProposalFeeRate, | ||
uint256 _referralAmount | ||
) private view returns (uint256 totalEscrowAmount) { | ||
return | ||
totalEscrowAmount = | ||
_amount + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just realize there is an issue here. The system can only work if we are taking the same fees that we do today on the _amount, for the _referralAmount. With fees it becomes sybil resistant |
||
(((_amount * protocolEscrowFeeRate) + | ||
(_amount * _originServiceFeeRate) + | ||
(_amount * _originValidatedProposalFeeRate)) / FEE_DIVIDER); | ||
(_amount * _originValidatedProposalFeeRate)) / FEE_DIVIDER) + | ||
_referralAmount; | ||
} | ||
|
||
// =========================== Overrides ============================== | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BalanceTransferred ?