The buy process of shares on the Aktionariat platform you can be trigger through off-chain as well as onchain transactions.
As the off-chain have to be executed by the issuer we focus in this guide on the onchain integration.
For the buy process with crypto currencies, payments are triggered via the PaymentHub contract.
The PaymentHub contract gives the possibility to buy shares with:
The base currency of the Brokerbot ( for now at all cases XCHF)
Ether
any ERC20 on Uniswap with a routing path
Get PaymentHub Address
The PaymentHub address is a public variable on the Brokerbot.
PaymentHub paymentHub = Brokerbot.paymenthub;
To know how to get a Brokerbot contract for a specific token see this guide.
Set Up Contract
contract BuySharesExample {
//constants
BrokerbotRegistry public constant BROKERBOT_REGISTRY = 0xcB3e482df38d62E73A7aE0E15a2605caDcc5aE98;
IERC20 public constant XCHF = 0xB4272071eCAdd69d933AdcD19cA99fe80664fc08;
// immutables
IERC20 public immutable share;
Brokerbot public immutable brokerbot;
PaymentHub public immutable paymenthub;
contstructor(IERC20 shareToken){
share = shareToken;
brokerbot = BROKERBOT_REGISTRY.getBrokerbot(XCHF,share);
paymenthub = brokerbot.paymenthub();
}
Buy with Base Currency (XCHF)
As every Brokerbot is paired with a base currency, the easiest is to buy with the base currency (in this example XCHF).
function buySharesWithBaseToken(uint256 amountShares) external {
uint256 baseAmount = brokerbot.getPrice(amountShares);
//approve paymenthub to move base currency (XCHF)
XCHF.approve(paymenthub, baseAmount)
paymenthub.payAndNotify(brokerbot, baseAmount, "0x01");
}
Buy with Ether
As the issuer mostly receives the paid amount in the base currency. We use Uniswap to facilitate the swap from Ether to the base currency.
If the issuer chooses to keep the amount paid in Ether (it has to be set in the Brokerbot settings), we use the Chainlink Oracle to get to make the conversion between base currency and Ether.
All overpaid Ether will be send back to the caller of the PaymentHub. Like this remember to have a receive / withdraw function for Ether if it is a contract.
But with any ERC20
As we have have the Uniswap Router integrated in the PaymentHub, you can use any valid swap path to buy with any ERC20. (See the Uniswap Multihop Swaps docs for more details)
For this example we show how you can buy with WTBC:
address public constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;
address public constan WETH9 = 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2;
uint24 public constant poolFee = 3000;
bytes path = abi.encodePacked(WBTC, poolFee, WETH9, poolFee, XCHF);
function buySharesWithERC20(uint256 amountShares, path) external {
uint256 baseAmount = brokerbot.getPrice(amountShares);
uint256 priceInERC20 = paymenthub.getPriceInERC20(baseAmount, path);
// add a bit slippage as it an excactOutPut swap
uint256 priceInERC20WithSlippage = (priceInERC20 * 101) / 100;
// infinity approve uniswap to use wbtc from paymenthub (needs to be done one for each ERC20)
paymenthub.approveERC20(WBTC);
// approve paymenthub to use wbtc from user
wbtc.approve(paymenthub, priceInERC20WithSlippage);
// make buy
paymenthub.payFromERC20AndNotify(brokerbot, baseAmount, WBTC, priceInERC20WithSlippage, path, "0x01");
}