Skip to content

Commit

Permalink
Implement agent functionality required for settlement operations
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelKim20 committed Oct 30, 2024
1 parent c9b56d7 commit 3692b88
Show file tree
Hide file tree
Showing 36 changed files with 1,870 additions and 385 deletions.
73 changes: 54 additions & 19 deletions packages/contracts/contracts/controllers/LoyaltyBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,29 +88,64 @@ contract LoyaltyBridge is LoyaltyBridgeStorage, Initializable, OwnableUpgradeabl
require(_tokenId == tokenId, "1713");
require(_account != systemAccount, "1053");

bytes32 dataHash = keccak256(
abi.encode(
block.chainid,
address(tokenContract),
_account,
address(this),
_amount,
ledgerContract.nonceOf(_account),
_expiry
)
address account = _account;
uint256 amount = _amount;
uint256 expiry = _expiry;
address signer;
address recurve1 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
block.chainid,
address(tokenContract),
account,
address(this),
amount,
ledgerContract.nonceOf(account),
expiry
)
)
),
_signature
);
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == _account, "1501");
require(_expiry > block.timestamp, "1506");
require(ledgerContract.tokenBalanceOf(_account) >= _amount, "1511");
require(_amount % 1 gwei == 0, "1030");
require(_amount > protocolFee, "1031");

ledgerContract.transferToken(_account, address(this), _amount);
ledgerContract.increaseNonce(_account);
if (recurve1 == account) {
signer = account;
} else {
address agent = ledgerContract.withdrawalAgentOf(account);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
block.chainid,
address(tokenContract),
account,
address(this),
amount,
ledgerContract.nonceOf(agent),
expiry
)
)
),
_signature
);
require(recurve2 == agent, "1501");
signer = agent;
}

require(expiry > block.timestamp, "1506");
require(ledgerContract.tokenBalanceOf(account) >= amount, "1511");
require(amount % 1 gwei == 0, "1030");
require(amount > protocolFee, "1031");

ledgerContract.transferToken(account, address(this), amount);
ledgerContract.increaseNonce(account);

DepositData memory data = DepositData({ tokenId: _tokenId, account: _account, amount: _amount });
DepositData memory data = DepositData({ tokenId: _tokenId, account: account, amount: amount });
deposits[_depositId] = data;
emit BridgeDeposited(_tokenId, _depositId, _account, _amount, ledgerContract.tokenBalanceOf(_account));
emit BridgeDeposited(_tokenId, _depositId, account, amount, ledgerContract.tokenBalanceOf(account));
}

/// @notice 브리지에서 자금을 인출합니다. 검증자들의 합의가 완료되면 인출이 됩니다.
Expand Down
6 changes: 3 additions & 3 deletions packages/contracts/contracts/controllers/LoyaltyProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ contract LoyaltyProvider is LoyaltyProviderStorage, Initializable, OwnableUpgrad
)
);
address recover = ECDSA.recover(ECDSA.toEthSignedMessageHash(purchaseDataHash), data.signature);
address agent = ledgerContract.provisioningAgentOf(data.sender);
address agent = ledgerContract.provisionAgentOf(data.sender);
if ((agent == address(0x0)) && (recover != data.sender)) continue;
if ((agent != address(0x0)) && (recover != agent)) continue;

Expand Down Expand Up @@ -285,7 +285,7 @@ contract LoyaltyProvider is LoyaltyProviderStorage, Initializable, OwnableUpgrad
if (recurve1 == _provider) {
sender = _provider;
} else {
address agent = ledgerContract.provisioningAgentOf(_provider);
address agent = ledgerContract.provisionAgentOf(_provider);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
Expand Down Expand Up @@ -331,7 +331,7 @@ contract LoyaltyProvider is LoyaltyProviderStorage, Initializable, OwnableUpgrad
if (recurve1 == _provider) {
sender = _provider;
} else {
address agent = ledgerContract.provisioningAgentOf(_provider);
address agent = ledgerContract.provisionAgentOf(_provider);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
Expand Down
6 changes: 5 additions & 1 deletion packages/contracts/contracts/interfaces/ILedger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,9 @@ interface ILedger {

function isProvider(address _account) external view returns (bool);

function provisioningAgentOf(address _account) external view returns (address);
function provisionAgentOf(address _account) external view returns (address);

function refundAgentOf(address _account) external view returns (address);

function withdrawalAgentOf(address _account) external view returns (address);
}
41 changes: 34 additions & 7 deletions packages/contracts/contracts/ledger/Ledger.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ contract Ledger is LedgerStorage, Initializable, OwnableUpgradeable, UUPSUpgrade
event RegisteredProvider(address provider);
event UnregisteredProvider(address provider);

event RegisteredProvisioningAgent(address account, address agent);
event RegisteredProvisionAgent(address account, address agent);
event RegisteredRefundAgent(address account, address agent);
event RegisteredWithdrawalAgent(address account, address agent);

struct ManagementAddresses {
address system;
Expand Down Expand Up @@ -513,17 +515,42 @@ contract Ledger is LedgerStorage, Initializable, OwnableUpgradeable, UUPSUpgrade
return providers[_account];
}

function registerProvisioningAgent(address _account, address _agent, bytes calldata _signature) external {
require(providers[_account], "1054");
function registerProvisionAgent(address _account, address _agent, bytes calldata _signature) external {
bytes32 dataHash = keccak256(abi.encode(_account, _agent, block.chainid, nonce[_account]));
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == _account, "1501");
provisioningAgents[_account] = _agent;
provisionAgents[_account] = _agent;
nonce[_account]++;

emit RegisteredProvisioningAgent(_account, _agent);
emit RegisteredProvisionAgent(_account, _agent);
}

function provisioningAgentOf(address _account) external view override returns (address) {
return provisioningAgents[_account];
function provisionAgentOf(address _account) external view override returns (address) {
return provisionAgents[_account];
}

function registerRefundAgent(address _account, address _agent, bytes calldata _signature) external {
bytes32 dataHash = keccak256(abi.encode(_account, _agent, block.chainid, nonce[_account]));
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == _account, "1501");
refundAgents[_account] = _agent;
nonce[_account]++;

emit RegisteredRefundAgent(_account, _agent);
}

function refundAgentOf(address _account) external view override returns (address) {
return refundAgents[_account];
}

function registerWithdrawalAgent(address _account, address _agent, bytes calldata _signature) external {
bytes32 dataHash = keccak256(abi.encode(_account, _agent, block.chainid, nonce[_account]));
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == _account, "1501");
withdrawalAgents[_account] = _agent;
nonce[_account]++;

emit RegisteredWithdrawalAgent(_account, _agent);
}

function withdrawalAgentOf(address _account) external view override returns (address) {
return withdrawalAgents[_account];
}
}
4 changes: 3 additions & 1 deletion packages/contracts/contracts/ledger/LedgerStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ contract LedgerStorage {
mapping(address => uint256) internal liquidity;

mapping(address => bool) internal providers;
mapping(address => address) internal provisioningAgents;
mapping(address => address) internal provisionAgents;
mapping(address => address) internal refundAgents;
mapping(address => address) internal withdrawalAgents;

address public systemAccount;
address public paymentFeeAccount;
Expand Down
141 changes: 112 additions & 29 deletions packages/contracts/contracts/shop/Shop.sol
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,31 @@ contract Shop is ShopStorage, Initializable, OwnableUpgradeable, UUPSUpgradeable
/// @param _shopId 상점아이디
/// @param _amount 인출금
/// @dev 중계서버를 통해서 상점주의 서명을 가지고 호출됩니다.
function refund(bytes32 _shopId, address _account, uint256 _amount, bytes calldata _signature) external virtual {
function refund(bytes32 _shopId, uint256 _amount, bytes calldata _signature) external virtual {
require(shops[_shopId].status == ShopStatus.ACTIVE, "1202");
bytes32 dataHash = keccak256(abi.encode(_shopId, _account, _amount, block.chainid, nonce[_account]));
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == _account, "1501");
require(shops[_shopId].account == _account, "1050");
require(_amount % 1 gwei == 0, "1030");
require(settlements[_shopId].manager == bytes32(0x0), "1552");

address signer;
address shopOwner = shops[_shopId].account;

address recurve1 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(keccak256(abi.encode(_shopId, _amount, block.chainid, nonce[shopOwner]))),
_signature
);

if (recurve1 == shopOwner) {
signer = shopOwner;
} else {
address agent = ledgerContract.refundAgentOf(shopOwner);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(keccak256(abi.encode(_shopId, _amount, block.chainid, nonce[agent]))),
_signature
);
require(recurve2 == agent, "1501");
signer = agent;
}

ShopData memory shop = shops[_shopId];
uint256 settlementAmount = (shop.collectedAmount + shop.usedAmount > shop.providedAmount)
Expand All @@ -385,16 +403,16 @@ contract Shop is ShopStorage, Initializable, OwnableUpgradeable, UUPSUpgradeable

require(_amount <= refundableAmount, "1220");

uint256 amountToken = currencyRate.convertCurrencyToToken(_amount, shops[_shopId].currency);
ledgerContract.refund(_account, _amount, shops[_shopId].currency, amountToken, _shopId);
uint256 amountToken = currencyRate.convertCurrencyToToken(_amount, shop.currency);
ledgerContract.refund(shopOwner, _amount, shop.currency, amountToken, shop.shopId);

shops[_shopId].refundedAmount += _amount;
nonce[_account]++;
shops[shop.shopId].refundedAmount += _amount;
nonce[signer]++;

uint256 balanceToken = ledgerContract.tokenBalanceOf(_account);
uint256 refundedTotal = shops[_shopId].refundedAmount;
string memory currency = shops[_shopId].currency;
emit Refunded(_shopId, _account, _amount, refundedTotal, currency, amountToken, balanceToken);
uint256 balanceToken = ledgerContract.tokenBalanceOf(shopOwner);
uint256 refundedTotal = shops[shop.shopId].refundedAmount;
string memory currency = shop.currency;
emit Refunded(_shopId, shopOwner, _amount, refundedTotal, currency, amountToken, balanceToken);
}

/// @notice nonce 를 리턴한다
Expand Down Expand Up @@ -523,13 +541,48 @@ contract Shop is ShopStorage, Initializable, OwnableUpgradeable, UUPSUpgradeable
"1554"
);

address account = shops[_managerShopId].account;
bytes32 dataHash = keccak256(
abi.encode("CollectSettlementAmount", _managerShopId, _clientShopId, block.chainid, nonce[account])
address sender;
address shopOwner = shops[_managerShopId].account;
address recurve1 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
"CollectSettlementAmount",
_managerShopId,
_clientShopId,
block.chainid,
nonce[shopOwner]
)
)
),
_signature
);
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == account, "1501");

nonce[account]++;
if (recurve1 == shopOwner) {
sender = shopOwner;
} else {
address agent = ledgerContract.refundAgentOf(shopOwner);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
"CollectSettlementAmount",
_managerShopId,
_clientShopId,
block.chainid,
nonce[agent]
)
)
),
_signature
);
require(recurve2 == agent, "1501");
sender = agent;
}

nonce[sender]++;

_collectSettlementAmount(_managerShopId, _clientShopId);
}
Expand All @@ -542,19 +595,49 @@ contract Shop is ShopStorage, Initializable, OwnableUpgradeable, UUPSUpgradeable
require(_managerShopId != bytes32(0x0), "1223");
require(shops[_managerShopId].status != ShopStatus.INVALID, "1201");

address account = shops[_managerShopId].account;
bytes32 dataHash = keccak256(
abi.encode(
"CollectSettlementAmountMultiClient",
_managerShopId,
_clientShopIds,
block.chainid,
nonce[account]
)
address sender;
address shopOwner = shops[_managerShopId].account;

address recurve1 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
"CollectSettlementAmountMultiClient",
_managerShopId,
_clientShopIds,
block.chainid,
nonce[shopOwner]
)
)
),
_signature
);
require(ECDSA.recover(ECDSA.toEthSignedMessageHash(dataHash), _signature) == account, "1501");

nonce[account]++;
if (recurve1 == shopOwner) {
sender = shopOwner;
} else {
address agent = ledgerContract.refundAgentOf(shopOwner);
require(agent != address(0x0), "1501");

address recurve2 = ECDSA.recover(
ECDSA.toEthSignedMessageHash(
keccak256(
abi.encode(
"CollectSettlementAmountMultiClient",
_managerShopId,
_clientShopIds,
block.chainid,
nonce[agent]
)
)
),
_signature
);
require(recurve2 == agent, "1501");
sender = agent;
}

nonce[sender]++;

for (uint256 idx = 0; idx < _clientShopIds.length; idx++) {
bytes32 clientShopId = _clientShopIds[idx];
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/deploy/side_chain_devnet/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -916,11 +916,11 @@ async function deployLedger(accounts: IAccount, deployment: Deployments) {
const signature = await ContractUtils.signMessage(accounts.system, message);
const tx = await contract
.connect(accounts.certifiers[0])
.registerProvisioningAgent(accounts.system.address, accounts.publisher.address, signature);
.registerProvisionAgent(accounts.system.address, accounts.publisher.address, signature);
console.log(`Register agent address of system (tx: ${tx.hash})...`);
// await tx.wait();

const value = await contract.provisioningAgentOf(accounts.system.address);
const value = await contract.provisionAgentOf(accounts.system.address);
console.log("Assistance of System Account: ", value);
}
}
Expand Down
Loading

0 comments on commit 3692b88

Please sign in to comment.