Skip to content

Commit

Permalink
Use a base ledger Atom in bond test
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Richardson <[email protected]>
  • Loading branch information
awrichar committed Dec 2, 2024
1 parent f2ba5fc commit 120d58f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ void testBond() throws Exception {
"contracts/shared/BondTrackerPublic.sol/BondTrackerPublic.json",
"abi"
);
String atomFactoryBytecode = ResourceLoader.jsonResourceEntryText(
this.getClass().getClassLoader(),
"contracts/shared/Atom.sol/AtomFactory.json",
"bytecode"
);
JsonABI atomFactoryABI = JsonABI.fromJSONResourceEntry(
this.getClass().getClassLoader(),
"contracts/shared/Atom.sol/AtomFactory.json",
"abi"
);
JsonABI atomABI = JsonABI.fromJSONResourceEntry(
this.getClass().getClassLoader(),
"contracts/shared/Atom.sol/Atom.json",
"abi"
);

GroupTupleJSON issuerCustodianGroup = new GroupTupleJSON(
JsonHex.randomBytes32(), new String[]{bondIssuer, bondCustodian});
Expand Down Expand Up @@ -218,12 +233,20 @@ void testBond() throws Exception {
var investorRegistry = bondTracker.investorRegistry(bondCustodian);
investorRegistry.addInvestor(bondCustodian, aliceAddress);

// Create the atom factory on the base ledger
String atomFactoryAddress = testbed.getRpcClient().request("testbed_deployBytecode",
"issuer",
atomFactoryABI,
atomFactoryBytecode,
new HashMap<String, String>());

// Alice deploys BondSubscription to the alice/custodian privacy group, to request subscription
// TODO: if Alice deploys, how can custodian trust it's the correct logic?
var bondSubscription = BondSubscriptionHelper.deploy(aliceCustodianInstance, alice, new HashMap<>() {{
put("bondAddress_", notoBond.address());
put("units_", 1000);
put("custodian_", custodianAddress);
put("atomFactory_", atomFactoryAddress);
}});

// Prepare the bond transfer (requires 2 calls to prepare, as the Noto transaction spawns a Pente transaction to wrap it)
Expand All @@ -249,25 +272,51 @@ void testBond() throws Exception {
bondSubscription.prepareBond(bondCustodian, bondTransfer2.preparedTransaction().to(), bondTransferMetadata.transitionWithApproval().encodedCall());
bondSubscription.preparePayment(alice, paymentTransfer.preparedTransaction().to(), paymentMetadata.transferWithApproval().encodedCall());

// Alice receives full bond distribution
bondSubscription.distribute(bondCustodian, 1000);

// Look up the deployed Atom
// TODO: use the AtomDeployed event instead of this method
HashMap<String, Object> queryResult = testbed.getRpcClient().request("ptx_call",
new Testbed.TransactionInput(
"public",
"",
bondCustodian,
JsonHex.addressFrom(atomFactoryAddress),
new HashMap<>(),
atomFactoryABI,
"lastDeploy"));
var atomAddress = JsonHex.addressFrom(queryResult.get("0").toString());

// Alice approves payment transfer
notoCash.approveTransfer(
"alice",
paymentTransfer.inputStates(),
paymentTransfer.outputStates(),
paymentMetadata.approvalParams().data(),
aliceCustodianInstance.address());
atomAddress.toString());

// Custodian approves bond transfer
issuerCustodianInstance.approveTransition(
bondCustodian,
JsonHex.randomBytes32(),
aliceCustodianInstance.address(),
atomAddress,
bondTransferMetadata.approvalParams().transitionHash(),
bondTransferMetadata.approvalParams().signatures());
Thread.sleep(3000); // TODO: wait for transaction receipt

// Alice receives full bond distribution
bondSubscription.distribute(bondCustodian, 1000);
// Execute the Atom
testbed.getRpcClient().request("ptx_sendTransaction",
new Testbed.TransactionInput(
"public",
"",
bondCustodian,
atomAddress,
new HashMap<>(),
atomABI,
"execute"
));
Thread.sleep(3000); // TODO: wait for transaction receipt

// TODO: figure out how to test negative cases (such as when Pente reverts due to a non-allowed investor)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public record ApproveExtraParams(
}

@JsonIgnoreProperties(ignoreUnknown = true)
public record NotoPublicTransaction(
public record PublicTransaction(
@JsonProperty
JsonABI.Entry functionABI,
@JsonProperty
Expand All @@ -96,7 +96,7 @@ public record NotoTransferMetadata(
@JsonProperty
ApproveExtraParams approvalParams,
@JsonProperty
NotoPublicTransaction transferWithApproval
PublicTransaction transferWithApproval
) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public Testbed.TransactionResult prepare(String sender, JsonABI.Entry fn, Map<St
"")));
}

public void approveTransition(String sender, JsonHex.Bytes32 txID, String delegate, JsonHex.Bytes32 transitionHash, List<JsonHex.Bytes> signatures) throws IOException {
public void approveTransition(String sender, JsonHex.Bytes32 txID, JsonHex.Address delegate, JsonHex.Bytes32 transitionHash, List<JsonHex.Bytes> signatures) throws IOException {
JsonABI.Entry fn = JsonABI.newFunction(
"approveTransition",
JsonABI.newParameters(
Expand Down
22 changes: 19 additions & 3 deletions solidity/contracts/private/BondSubscription.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.20;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IPenteExternalCall} from "./interfaces/IPenteExternalCall.sol";
import {Atom, AtomFactory} from "../shared/Atom.sol";

/**
* @title BondSubscription
Expand All @@ -13,6 +14,7 @@ contract BondSubscription is Ownable, IPenteExternalCall {
address public custodian;
uint256 public requestedUnits;
uint256 public receivedUnits;
address public atomFactory;

address internal distributeBondAddress;
bytes internal distributeBondCall;
Expand All @@ -27,11 +29,13 @@ contract BondSubscription is Ownable, IPenteExternalCall {
constructor(
address bondAddress_,
uint256 units_,
address custodian_
address custodian_,
address atomFactory_
) Ownable(_msgSender()) {
bondAddress = bondAddress_;
requestedUnits = units_;
custodian = custodian_;
atomFactory = atomFactory_;
}

function preparePayment(
Expand Down Expand Up @@ -65,7 +69,19 @@ contract BondSubscription is Ownable, IPenteExternalCall {
"Payment transfer has not been prepared"
);
receivedUnits += units_;
emit PenteExternalCall(distributeBondAddress, distributeBondCall);
emit PenteExternalCall(distributePaymentAddress, distributePaymentCall);

Atom.Operation[] memory operations = new Atom.Operation[](2);
operations[0] = Atom.Operation(
distributeBondAddress,
distributeBondCall
);
operations[1] = Atom.Operation(
distributePaymentAddress,
distributePaymentCall
);
emit PenteExternalCall(
atomFactory,
abi.encodeCall(AtomFactory.create, operations)
);
}
}
12 changes: 7 additions & 5 deletions solidity/contracts/shared/Atom.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "../domains/interfaces/INoto.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {INoto} from "../domains/interfaces/INoto.sol";

contract Atom is Initializable {
uint256 private _operationCount;
Expand Down Expand Up @@ -66,6 +66,7 @@ contract Atom is Initializable {

contract AtomFactory {
address public immutable logic;
address public lastDeploy; // TODO: remove and listen to AtomDeployed

event AtomDeployed(address addr);

Expand All @@ -84,6 +85,7 @@ contract AtomFactory {
address addr = address(
new ERC1967Proxy(logic, _initializationCalldata)
);
lastDeploy = addr;
emit AtomDeployed(addr);
}
}

0 comments on commit 120d58f

Please sign in to comment.