Skip to content

Commit

Permalink
Merge branch 'main' of github.com:svub/nunya
Browse files Browse the repository at this point in the history
  • Loading branch information
svub committed Oct 6, 2024
2 parents 6325846 + 6bfecba commit 84112be
Showing 1 changed file with 69 additions and 34 deletions.
103 changes: 69 additions & 34 deletions packages/hardhat/contracts/payWithEth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interface SecretContract {
contract NunyaBusiness {

enum FunctionCallType {
OTHER, NEW_USER, NEW_REF, PAY, WITHDRAW
OTHER, NEW_USER, NEW_REF, PAY, WITHDRAW, ERROR
}

struct Receipt {
Expand All @@ -30,19 +30,24 @@ contract NunyaBusiness {
bytes32 sig;
}

address gateway;
address payable gateway;
SecretContract secretContract;
uint256 secretContractPubkey;
mapping (uint256 => FunctionCallType) expectedResult;

event receiptEmitted(Receipt);
event ReceiptEmitted(Receipt);
event Request_success(uint256 requestId);
event SecretNetworkError(uint256 requestId, string message);
event HackingAttemptError(uint256 requestId);

constructor(address _gateway) {
constructor(address payable _gateway) payable {
gateway = _gateway;
secretContract = SecretContract(_gateway);
// Lock secretContractPubkey to requestId so that only that request cn set it.
// TODO: make it better - if call fails, contract is stuck and needs redploy :P
secretContractPubkey = secretContract.retrievePubkey();
fundGateway(msg.value);

secretContract.retrievePubkey();
// Lock secretContractPubkey to Owner. After it is set it cannot be reset.
secretContractPubkey = uint256(uint160(msg.sender));
}

modifier onlyGateway {
Expand All @@ -51,53 +56,60 @@ contract NunyaBusiness {
_;
}

function setSecretContractPubkeyCallback (uint256 requestId, uint256 _key) public onlyGateway {
function setSecretContractPubkeyCallback (uint256 _requestId, uint256 _key) public onlyGateway {
// require (secretContractPubkey==0, "Key already set");
require (secretContractPubkey==requestId, "Only the contract constructor can trigger this function");
// TODO: Make sure it's our secret contract setting the key, not some interloper
// Make sure it's our secret contract setting the key, not some interloper
// (will fail one time in 2^96 ;)
require (secretContractPubkey < 2**160, "Only the contract constructor can trigger this function");
secretContractPubkey=_key;
}

// Function wrapped in secret network payload encryption
function newSecretUser(uint256 _secret) public returns (uint256){
function newSecretUser(uint256 _secret) public payable returns (uint256){
fundGateway(msg.value);
uint256 requestId = secretContract.newSecretUser(_secret);
expectedResult[requestId]==FunctionCallType.NEW_USER;
return(requestId);
}

function newSecretUserCallback(uint256 requestId) public onlyGateway {
require (expectedResult[requestId]==FunctionCallType.NEW_USER);
// TODO: emit requestId
function newSecretUserCallback(uint256 _requestId, bool _success) public onlyGateway {
require (expectedResult[_requestId]==FunctionCallType.NEW_USER);
if (!_success)
emit SecretNetworkError(_requestId, "Error paying - duplicate user?");
emit Request_success(_requestId);
}

// Function wrapped in secret network payload encryption
function linkPaymentRef(uint256 _secret, string calldata _ref) public returns (uint256){
function linkPaymentRef(uint256 _secret, string calldata _ref) public payable returns (uint256){
fundGateway(msg.value);
uint256 requestId = secretContract.linkPaymentRef(_secret, _ref);
expectedResult[requestId]=FunctionCallType.NEW_REF;
return(requestId);
}

function linkPaymentRefCallback(uint256 requestId) public onlyGateway{
require (expectedResult[requestId]==FunctionCallType.NEW_REF);
// TODO : emit requestId
function linkPaymentRefCallback(uint256 _requestId, bool _success) public onlyGateway{
require (expectedResult[_requestId]==FunctionCallType.NEW_REF);
if (!_success)
emit SecretNetworkError(_requestId, "Error paying - no user found?");
emit Request_success(_requestId);
}

// TODO: use ref encrypted with (user pubkey+salt)
function pay(string calldata ref, uint256 _value) public payable returns (uint256) {
function pay(string calldata _ref, uint256 _value) public payable returns (uint256) {
// >= because we need gas for
require (_value >= msg.value, "Naughty!");
uint256 gasPaid = fundGateway();
uint256 requestId = secretContract.pay(ref, msg.value-gasPaid);
uint256 requestId = secretContract.pay(_ref, msg.value-gasPaid);
expectedResult[requestId]=FunctionCallType.PAY;
return(requestId);
}

// TODO: use ref encrypted with (user pubkey+salt)
function pay(string calldata ref, uint256 _value, uint256 _userPubkey) public payable returns (uint256) {
function pay(string calldata _ref, uint256 _value, uint256 _userPubkey) public payable returns (uint256) {
// >= because we need gas for
require (_value >= msg.value, "Naughty!");
uint256 gasPaid = fundGateway();
uint256 requestId = secretContract.payWithReceipt(ref, msg.value-gasPaid, _userPubkey);
uint256 requestId = secretContract.payWithReceipt(_ref, msg.value-gasPaid, _userPubkey);
expectedResult[requestId]==FunctionCallType.PAY;
return(requestId);
}
Expand All @@ -107,36 +119,59 @@ contract NunyaBusiness {
// secretContract.pay()
// }

function fundGateway(uint256 _gas) internal returns (uint256) {
gateway.transfer(_gas);
return _gas;
}

function fundGateway() internal returns (uint256) {
// TODO: calculate gas better than this!
uint256 gas=1;
// TODO: write the function
gateway.transfer(gas);
return gas;
}

function payCallback(uint256 requestId, Receipt calldata _receipt) public payable onlyGateway {
function payCallback(uint256 _requestId, bool _success) public payable onlyGateway {
require (expectedResult[_requestId]==FunctionCallType.PAY);
if (!_success)
emit SecretNetworkError(_requestId, "Error paying - wrong payment ref?");
emit Request_success(_requestId);
}

function payCallback(uint256 _requestId, bool _success, Receipt calldata _receipt) public payable onlyGateway {
// TODO : use ecrecover to check receipt is signed by secret contract
require (expectedResult[requestId]==FunctionCallType.PAY);
require (expectedResult[_requestId]==FunctionCallType.PAY);
if (!_success)
emit SecretNetworkError(_requestId, "Error paying - wrong payment ref?");
if (uint256(_receipt.sig)!=0)
emit receiptEmitted(_receipt);
// TODO : emit requestId
emit ReceiptEmitted(_receipt);
emit Request_success(_requestId);
}

receive() external payable {

}

// Function wrapped in secret network payload encryption
function withdrawTo(string calldata secret, uint256 amount, address withdrawalAddress) public returns (uint256) {
require((amount > 0), "Account not found or empty.");
uint256 requestId = secretContract.withdraw(secret, withdrawalAddress);
function withdrawTo(string calldata _secret, uint256 _amount, address _withdrawalAddress) public payable returns (uint256) {
require((_amount > 0), "Account not found or empty.");
fundGateway(msg.value);
uint256 requestId = secretContract.withdraw(_secret, _withdrawalAddress);
// TODO: error check
expectedResult[requestId]=FunctionCallType.WITHDRAW;
return(requestId);
}

function withdrawToCallback(uint256 requestId, uint256 amount, address payable withdrawalAddress) onlyGateway public {
require (expectedResult[requestId]==FunctionCallType.WITHDRAW);
require(amount > 0, "Account not found or empty.");
withdrawalAddress.transfer(amount);
function withdrawToCallback(uint256 _requestId, bool _success, uint256 _amount, address payable _withdrawalAddress) onlyGateway public {
require (expectedResult[_requestId]==FunctionCallType.WITHDRAW);
if (!_success)
emit SecretNetworkError(_requestId, "Error withdrawing - out of funds?");
require(_amount > 0, "Account not found or empty.");
_withdrawalAddress.transfer(_amount);
emit Request_success(_requestId);
}

function emitSecretNetworkError(uint256 _requestId, string memory _message) public onlyGateway {
emit SecretNetworkError(_requestId, _message);
}
}

0 comments on commit 84112be

Please sign in to comment.