Skip to content

Commit

Permalink
✨ [blockchain]: Refactoring related to PR comments, #121
Browse files Browse the repository at this point in the history
  • Loading branch information
jtse0 authored and solomondefi-dev committed Nov 22, 2021
1 parent 1c74713 commit 70bd176
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 46 deletions.
1 change: 1 addition & 0 deletions apps/contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ typechain/

log
*.env
.pnpm-debug.log
19 changes: 0 additions & 19 deletions apps/contracts/.pnpm-debug.log

This file was deleted.

9 changes: 6 additions & 3 deletions apps/contracts/src/contracts/SlmChargeback.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
pragma solidity 0.8.9;

import "./library/SlmShared.sol";
import "./library/SlmJudgement.sol";
import "hardhat/console.sol";

/// @title Solomon Chargeback
/// @author Solomon DeFi
/// @notice A contract that holds ETH or ERC20 tokens until purchase conditions are met
contract SlmChargeback is SlmShared {

uint8 public discount;
SlmJudgement public judgement;

/// Initialize the contract
/// @param _judge Contract that assigns votes for chargeback disputes
Expand Down Expand Up @@ -60,15 +63,15 @@ contract SlmChargeback is SlmShared {
/// Allow buyer to withdraw if eligible
function buyerWithdraw(bytes32 encryptionKey) external {
require(msg.sender == buyer(), "Only buyer can withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == 2, "Cannot withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == SlmJudgement.VoteStates.BuyerWins, "Cannot withdraw");
state = TransactionState.CompleteParty1;
withdraw(buyer());
}

/// Allow merchant to withdraw if eligible
function merchantWithdraw(bytes32 encryptionKey) external {
require(msg.sender == merchant(), "Only merchant can withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == 3, "Cannot withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == SlmJudgement.VoteStates.MerchantWins, "Cannot withdraw");
state = TransactionState.CompleteParty2;
withdraw(merchant());
}
Expand Down
15 changes: 11 additions & 4 deletions apps/contracts/src/contracts/SlmEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.9;

import "./library/SlmShared.sol";
import "./library/SlmJudgement.sol";

/// @title Solomon Escrow
/// @author Solomon DeFi
Expand Down Expand Up @@ -66,12 +67,18 @@ contract SlmEscrow is SlmShared {
/// Allow either party to withdraw if eligible
function withdrawFunds(bytes32 encryptionKey) external {
require(msg.sender == _party1 || msg.sender == _party2, "Only parties can withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == 2 || judge.getVoteResults(address(this), encryptionKey) == 3, "Cannot withdraw");

bool eligibleWithdrawal = false;
SlmJudgement.VoteStates voteResult = judge.getVoteResults(address(this), encryptionKey);
if(voteResult == SlmJudgement.VoteStates.BuyerWins || voteResult == SlmJudgement.VoteStates.MerchantWins) {
eligibleWithdrawal = true;
}
require(eligibleWithdrawal, "Cannot withdraw");

state = TransactionState.CompleteParty1;
uint8 voteResult = judge.getVoteResults(address(this), encryptionKey);
if (voteResult == 2) {
if (voteResult == SlmJudgement.VoteStates.BuyerWins) {
withdraw(_party1);
} else if (voteResult == 3) {
} else if (voteResult == SlmJudgement.VoteStates.BuyerWins) {
withdraw(_party2);
}
}
Expand Down
5 changes: 3 additions & 2 deletions apps/contracts/src/contracts/SlmPreorder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.9;

import "./library/SlmShared.sol";
import "./library/SlmJudgement.sol";

/// @title Solomon Preorder
/// @author Solomon DeFi
Expand Down Expand Up @@ -60,15 +61,15 @@ contract SlmPreorder is SlmShared {
/// Allow buyer to withdraw if eligible
function buyerWithdraw(bytes32 encryptionKey) external {
require(msg.sender == buyer(), "Only buyer can withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == 2, "Cannot withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == SlmJudgement.VoteStates.BuyerWins, "Cannot withdraw");
state = TransactionState.CompleteParty1;
withdraw(buyer());
}

/// Allow merchant to withdraw if eligible
function merchantWithdraw(bytes32 encryptionKey) external {
require(msg.sender == merchant(), "Only merchant can withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == 3, "Cannot withdraw");
require(judge.getVoteResults(address(this), encryptionKey) == SlmJudgement.VoteStates.MerchantWins, "Cannot withdraw");
state = TransactionState.CompleteParty2;
withdraw(merchant());
}
Expand Down
53 changes: 35 additions & 18 deletions apps/contracts/src/contracts/library/SlmJudgement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,19 @@ contract SlmJudgement is Ownable {
uint16 public minJurorCount;
uint256[] private selectedJurors;

enum VoteStates {
Inactive,
InsufficientVotes,
BuyerWins,
MerchantWins,
Tie
}

VoteStates public states;

mapping(address => bool) public adminList;

mapping(address => uint8) public voteResults;
mapping(address => VoteStates) public voteResults;

/// Record of SLM contracts to chargeback/escrow votes
mapping(address => Dispute) public disputes;
Expand Down Expand Up @@ -68,12 +78,19 @@ contract SlmJudgement is Ownable {
bool tieBreakComplete;
}

enum MemberRole {
Inactive,
Merchant,
Buyer,
Juror
}

struct Role {
// Member role
// 1 == Merchant
// 2 == Buyer
// 3 == Juror
mapping(address => uint8) memberRoles;
mapping(address => MemberRole) memberRoles;
mapping(address => bytes32) encryptedKeyList;
}

Expand Down Expand Up @@ -107,7 +124,7 @@ contract SlmJudgement is Ownable {
stakerManager.setVoteDetails(slmContract, endTime);
}

function setDisputeAccess(address slmContract, uint8[] memory roles, address[] memory addressList, bytes32[] memory keyList) external onlyOwner {
function setDisputeAccess(address slmContract, MemberRole[] memory roles, address[] memory addressList, bytes32[] memory keyList) external onlyOwner {
require(slmContract != address(0), "Zero addr");
require(addressList.length == keyList.length && keyList.length == roles.length, "Invalid array length");
require(roles.length > 0, "Empty array");
Expand All @@ -122,7 +139,7 @@ contract SlmJudgement is Ownable {
require(slmContract != address(0), "Zero addr");
require(disputes[slmContract].voteEndTime > block.timestamp, "Voting has ended");
Role storage roles = disputeRoles[slmContract];
require(roles.memberRoles[msg.sender] == 3, "Voter ineligible");
require(roles.memberRoles[msg.sender] == MemberRole.Juror, "Voter ineligible");
if (roles.encryptedKeyList[msg.sender] == keccak256(abi.encodePacked(msg.sender, encryptionKey, _voteForBuyer))) {
if (disputes[slmContract].votes[msg.sender] == 0) {
disputes[slmContract].buyerVoteCount += 1;
Expand Down Expand Up @@ -177,20 +194,20 @@ contract SlmJudgement is Ownable {
tieBreakerEndTimes[slmContract] = block.timestamp + tieBreakerDuration;
}

function tieBreaker(address slmContract, bool buyerWins) external {
function tieBreaker(address slmContract, bool voteForBuyer) external {
require(slmContract != address(0), "Zero addr");
require(disputes[slmContract].voteEndTime < block.timestamp, "Voting period still active");
if (tieBreakerEndTimes[slmContract] < block.timestamp) {
voteResults[slmContract] = 2;
voteResults[slmContract] = VoteStates.BuyerWins;
} else {
require(tieBreakerEndTimes[slmContract] > block.timestamp, "Tie breaker has ended");
require(adminList[msg.sender] == true, "Not an admin");
require(voteResults[slmContract] == 4, "Not a tie");
require(voteResults[slmContract] == VoteStates.Tie, "Not a tie");

if (buyerWins) {
voteResults[slmContract] = 2;
if (voteForBuyer) {
voteResults[slmContract] = VoteStates.BuyerWins;
} else {
voteResults[slmContract] = 3;
voteResults[slmContract] = VoteStates.MerchantWins;
}
}
}
Expand All @@ -204,29 +221,29 @@ contract SlmJudgement is Ownable {
uint16 buyerVotes = dispute.buyerVoteCount;
// No vote exists
if (dispute.quorum == 0) {
voteResults[slmContract] = 0;
voteResults[slmContract] = VoteStates.Inactive;
// Vote not complete
} else if (merchantVotes + buyerVotes < dispute.quorum) {
voteResults[slmContract] = 1;
voteResults[slmContract] = VoteStates.InsufficientVotes;
} else if (buyerVotes > merchantVotes) {
voteResults[slmContract] = 2;
voteResults[slmContract] = VoteStates.BuyerWins;
} else if (merchantVotes > buyerVotes) {
voteResults[slmContract] = 3;
voteResults[slmContract] = VoteStates.MerchantWins;
// Tie breaker
} else {
voteResults[slmContract] = 4;
voteResults[slmContract] = VoteStates.Tie;
if (dispute.voteEndTime < block.timestamp) {
_startTieBreaker(slmContract);
}
}
}

function getVoteResults(address slmContract, bytes32 encryptionKey) external view returns(uint8) {
function getVoteResults(address slmContract, bytes32 encryptionKey) external view returns(VoteStates) {
require(slmContract != address(0), "Zero addr");
Dispute storage dispute = disputes[slmContract];
Role storage roles = disputeRoles[slmContract];
if (dispute.voteEndTime > block.timestamp || tieBreakerEndTimes[slmContract] > block.timestamp) {
require(roles.memberRoles[msg.sender] == 1 || roles.memberRoles[msg.sender] == 2 || adminList[msg.sender] == true, "Unauthorized role");
require(roles.memberRoles[msg.sender] == MemberRole.Merchant || roles.memberRoles[msg.sender] == MemberRole.Buyer || adminList[msg.sender] == true, "Unauthorized role");
require(roles.encryptedKeyList[msg.sender] == keccak256(abi.encodePacked(msg.sender, encryptionKey)), "Unauthorized access");
return voteResults[slmContract];
}
Expand Down Expand Up @@ -269,7 +286,7 @@ contract SlmJudgement is Ownable {
selectedJurors.push(stakerPool[selectedStartCount]);

userAddress = stakerManager.getUserAddress(selectedJurors[i]);
roles.memberRoles[userAddress] = 3;
roles.memberRoles[userAddress] = MemberRole.Juror;

i += 1;
selectedStartCount += 1;
Expand Down

0 comments on commit 70bd176

Please sign in to comment.