Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ledger referral ID for better tracking #12

Merged
merged 13 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ APPNAME = "Staderlabs"
# Application version
APPVERSION_M = 1
APPVERSION_N = 1
APPVERSION_P = 1
APPVERSION_P = 2
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"

# Initialize plugin SDK submodule if needed
Expand Down
64 changes: 64 additions & 0 deletions PLUGIN_SPECIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Technical Specification

## About

This documentation describes the smart contracts and functions supported by the staderlabs plugin.

#### MATICx

| Network | Contract Name | Smart Contract |
| -------- | ------------- | -------------------------------------------- |
| Ethereum | MaticX | `0xf03a7eb46d01d9ecaa104558c732cf82f6b6b645` |
| Polygon | ChildPool | `0xfd225c9e6601c9d38d8f98d8731bf59efcf8c0e3` |

Functions covered by above contract/s :
|Contract | Function | Selector | Displayed Parameters |
| --- | --- | --- | --- |
|MaticX | submit(uint256 \_amount) | `0xea99c2a6`| `_amount` |
|MaticX | requestWithdraw(uint256 \_amount) | `0x745400c9`| `_amount` |
|MaticX | claimWithdrawal(uint256 \_idx) | `0xf8444436`| |
|ChildPool | swapMaticForMaticXViaInstantPool() | `0xc78cf1a0`| native_token_amount (matic) |
|ChildPool | requestMaticXSwap(uint256 \_amount) | `0x48eaf6d6`| `_amount` |
|ChildPool | claimMaticXSwap(uint256 \_idx) | `0x77baf209`| |

#### BNBx

| Network | Contract Name | Smart Contract |
| ------- | ------------- | -------------------------------------------- |
| BSC | StakeManager | `0x7276241a669489E4BBB76f63d2A43Bfe63080F2F` |

Functions covered by above contract/s :
|Contract | Function | Selector | Displayed Parameters |
| --- | --- | --- | --- |
|StakeManager | deposit() | `0xd0e30db0`| native_token_amount (bnb) |
|StakeManager | requestWithdraw(uint256 \_amountInBnbX) | `0x745400c9`| `_amountInBnbX` |
|StakeManager | claimWithdraw(uint256 \_idx) | `0xb13acedd`| |

#### FTMx

| Network | Contract Name | Smart Contract |
| ------- | ------------- | -------------------------------------------- |
| Fantom | FTMStaking | `0xb458bfc855ab504a8a327720fcef98886065529b` |

Functions covered by above contract/s :
|Contract | Function | Selector | Displayed Parameters |
| --- | --- | --- | --- |
|FTMStaking | deposit() | `0xd0e30db0`| native_token_amount (ftm) |
|FTMStaking | undelegate(uint256 wrID, uint256 amountFTMx, uint256 minAmountFTM) | `0x4f864df4`| `amountFTMx` |
|FTMStaking | withdraw(uint256 wrID, uint256 bitmaskToSkip) | `0x441a3e70`| |

#### ETHx

| Network | Contract Name | Smart Contract |
| -------- | ----------------------- | -------------------------------------------- |
| Ethereum | StaderStakePoolsManager | `0xcf5ea1b38380f6af39068375516daf40ed70d299` |
| Ethereum | UserWithdrawalManager | `0x9f0491b32dbce587c50c4c43ab303b06478193a7` |

Functions covered by above contract/s :
|Contract | Function | Selector | Displayed Parameters |
| --- | --- | --- | --- |
|StaderStakePoolsManager | deposit(address \_receiver, string calldata \_referralId) | `0xb7482509`| `_receiver`, native_token_amount (eth) |
|UserWithdrawalManager | requestWithdraw(uint256 \_ethXAmount, address \_owner, string calldata \_referralId) | `0x1f7ec122`| `_ethXAmount`, `_owner` |
|UserWithdrawalManager | claim(uint256 \_requestId) | `0x379607f5`| |
|StaderStakePoolsManager | deposit(address \_receiver) | `0xf340fa01`| `_receiver`, native_token_amount (eth) |
|UserWithdrawalManager | requestWithdraw(uint256 \_ethXAmount, address \_owner) | `0xccc143b8`| `_ethXAmount`, `_owner` |
62 changes: 29 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,56 @@

This is a plugin for the Ethereum application which helps parsing and displaying relevant information when signing a Staderlabs transaction.

## Prerequisite
## Setup

Clone the plugin to a new folder.

```shell
git clone https://github.com/stader-labs/app-plugin-staderlabs.git
mkdir staderlabs_plugin_folder
cd staderlabs_plugin_folder

git clone --recurse-submodules https://github.com/LedgerHQ/app-plugin-staderlabs.git
```

Then in the same folder clone two more repositories, which is the plugin-tools and app-ethereum.
Then in the same folder clone app-ethereum.

```shell
git clone https://github.com/LedgerHQ/plugin-tools.git #plugin-tools
git clone --recurse-submodules https://github.com/LedgerHQ/app-ethereum.git #app-ethereum
```

## Documentation

Need more information about the interface, the architecture, or general stuff about ethereum plugins? You can find more about them in the [ethereum-app documentation](https://github.com/LedgerHQ/app-ethereum/blob/master/doc/ethapp_plugins.asc).

## Smart Contracts

Smart contracts covered by this plugin are:

| Network | Contract Name | Smart Contract |
| -------- | ----------------------- | -------------------------------------------- |
| Ethereum | MaticX | `0xf03a7eb46d01d9ecaa104558c732cf82f6b6b645` |
| Polygon | ChildPool | `0xfd225c9e6601c9d38d8f98d8731bf59efcf8c0e3` |
| BSC | StakeManager | `0x7276241a669489E4BBB76f63d2A43Bfe63080F2F` |
| Fantom | FTMStaking | `0xb458bfc855ab504a8a327720fcef98886065529b` |
| Ethereum | StaderStakePoolsManager | `0xcf5ea1b38380f6af39068375516daf40ed70d299` |
| Ethereum | UserWithdrawalManager | `0x9f0491b32dbce587c50c4c43ab303b06478193a7` |

## Build

Go to the plugin-tools folder and run the "./start" script.
Launch the docker

```shell
cd plugin-tools # go to plugin folder
./start.sh # run the script start.sh
brew install coreutils #For mac users if below command errors out (realpath doesn't exist)
sudo docker run --rm -ti -v "$(realpath .):/app" --user $(id -u $USER):$(id -g $USER) ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest
```

The script will build a docker image and attach a console.
When the docker image is running go to the "app-plugin-staderlabs" folder and build the ".elf" files.
From the Docker console

```shell
cd app-plugin-staderlabs/tests # go to the tests folder in app-plugin-staderlabs
./build_local_test_elfs.sh # run the script build_local_test_elfs.sh
#build the staderlabs plugin
cd app-plugin-staderlabs
make

#go to tests folder inside staderlabs plugin and build the ".elf" files for testing
cd tests
./build_local_test_elfs.sh
```

## Tests

To test the plugin go to the tests folder from the "app-plugin-staderlabs" and run the script "test"
Open a new Terminal and go to staderlabs_plugin_folder

```shell
cd app-plugin-staderlabs/tests # go to the tests folder in app-plugin-staderlabs
yarn test # run the script test
cd app-plugin-staderlabs/tests #go to tests folder inside app-plugin-staderlabs
yarn install #install node packages
yarn test #run tests
```

## Ethereum-App

Need more information about the interface, the architecture, or general stuff about ethereum plugins? You can find more about them in the [ethereum-app documentation](https://github.com/LedgerHQ/app-ethereum/blob/master/doc/ethapp_plugins.asc).

## Smart Contracts

Smart contracts covered by this plugin are documented in [PLUGIN_SPECIFICATON.md](https://github.com/LedgerHQ/app-plugin-staderlabs/blob/develop/PLUGIN_SPECIFICATION.md)
27 changes: 21 additions & 6 deletions src/contract.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,35 @@ static const uint32_t FTM_WITHDRAW_SELECTOR = 0x441a3e70;

// Network: Ethereum
// Contract: StaderStakePoolsManager
// Method: function deposit(address _receiver)
// Selector: 0xf340fa01
static const uint32_t ETHX_DEPOSIT_SELECTOR = 0xf340fa01;
// Method: function deposit(address _receiver, string calldata _referralId)
// Selector: 0xb7482509
static const uint32_t ETHX_DEPOSIT_SELECTOR = 0xb7482509;

// Network: Ethereum
// Contract: UserWithdrawalManager
// Method: function requestWithdraw(uint256 _ethXAmount, address _owner)
// Selector: 0xccc143b8
static const uint32_t ETHX_REQUEST_WITHDRAW_SELECTOR = 0xccc143b8;
// Method:
// function requestWithdraw(uint256 _ethXAmount, address _owner, string calldata _referralId)
// Selector: 0x1f7ec122
static const uint32_t ETHX_REQUEST_WITHDRAW_SELECTOR = 0x1f7ec122;

// Network: Ethereum
// Contract: UserWithdrawalManager
// Method: function claim(uint256 _requestId)
// Selector: 0x379607f5
static const uint32_t ETHX_CLAIM_SELECTOR = 0x379607f5;

// Network: Ethereum
// Contract: StaderStakePoolsManager
// Method: function deposit(address _receiver)
// Selector: 0xf340fa01
static const uint32_t ETHX_DEPOSIT_LEGACY_SELECTOR = 0xf340fa01;

// Network: Ethereum
// Contract: UserWithdrawalManager
// Method: function requestWithdraw(uint256 _ethXAmount, address _owner)
// Selector: 0xccc143b8
static const uint32_t ETHX_REQUEST_WITHDRAW_LEGACY_SELECTOR = 0xccc143b8;

// Array of all the different staderlabs selectors. Make sure this follows the same order as the
// enum defined in `staderlabs_plugin.h`
const uint32_t STADERLABS_SELECTORS[NUM_SELECTORS] = {
Expand All @@ -129,4 +142,6 @@ const uint32_t STADERLABS_SELECTORS[NUM_SELECTORS] = {
ETHX_DEPOSIT_SELECTOR,
ETHX_REQUEST_WITHDRAW_SELECTOR,
ETHX_CLAIM_SELECTOR,
ETHX_DEPOSIT_LEGACY_SELECTOR,
ETHX_REQUEST_WITHDRAW_LEGACY_SELECTOR,
};
2 changes: 2 additions & 0 deletions src/handle_finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ void handle_finalize(ethPluginFinalize_t *msg) {

switch (context->selectorIndex) {
case ETHX_DEPOSIT:
case ETHX_DEPOSIT_LEGACY:
case ETHX_REQUEST_WITHDRAW:
case ETHX_REQUEST_WITHDRAW_LEGACY:
msg->numScreens = 2;
break;

Expand Down
2 changes: 2 additions & 0 deletions src/handle_init_contract.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ void handle_init_contract(ethPluginInitContract_t *msg) {
// EDIT THIS: Adapt the `cases`, and set the `next_param` to be the first parameter you expect
// to parse.
switch (context->selectorIndex) {
case ETHX_DEPOSIT_LEGACY:
case ETHX_DEPOSIT:
context->next_param = ACCOUNT_ADDR;
context->ticker = "ETH";
break;

case ETHX_REQUEST_WITHDRAW_LEGACY:
case ETHX_REQUEST_WITHDRAW:
context->next_param = UNSTAKE_AMOUNT;
context->ticker = "ETHX";
Expand Down
10 changes: 10 additions & 0 deletions src/handle_provide_parameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ static void handle_unstake(ethPluginProvideParameter_t *msg, context_t *context)
}

static void handle_ethx_deposit(ethPluginProvideParameter_t *msg, context_t *context) {
if (context->skip_next_param) {
return;
}
switch (context->next_param) {
case ACCOUNT_ADDR:
copy_address(context->account_addr, msg->parameter, sizeof(context->account_addr));
context->next_param = UNEXPECTED_PARAMETER;
context->skip_next_param = true;
break;

// Keep this
Expand All @@ -61,6 +65,9 @@ static void handle_ethx_deposit(ethPluginProvideParameter_t *msg, context_t *con
}

static void handle_ethx_request_withdraw(ethPluginProvideParameter_t *msg, context_t *context) {
if (context->skip_next_param) {
return;
}
switch (context->next_param) {
case UNSTAKE_AMOUNT:
handle_amount_received(msg, context);
Expand All @@ -70,6 +77,7 @@ static void handle_ethx_request_withdraw(ethPluginProvideParameter_t *msg, conte
case ACCOUNT_ADDR:
copy_address(context->account_addr, msg->parameter, sizeof(context->account_addr));
context->next_param = UNEXPECTED_PARAMETER;
context->skip_next_param = true;
break;

// Keep this
Expand All @@ -93,10 +101,12 @@ void handle_provide_parameter(ethPluginProvideParameter_t *msg) {

// EDIT THIS: adapt the cases and the names of the functions.
switch (context->selectorIndex) {
case ETHX_DEPOSIT_LEGACY:
case ETHX_DEPOSIT:
handle_ethx_deposit(msg, context);
break;

case ETHX_REQUEST_WITHDRAW_LEGACY:
case ETHX_REQUEST_WITHDRAW:
handle_ethx_request_withdraw(msg, context);
break;
Expand Down
2 changes: 2 additions & 0 deletions src/handle_query_contract_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void handle_query_contract_id(ethQueryContractID_t *msg) {
// EDIT THIS: Adapt the cases by modifying the strings you pass to `strlcpy`.
switch (context->selectorIndex) {
case ETHX_DEPOSIT:
case ETHX_DEPOSIT_LEGACY:
case ETH_MATICX_SUBMIT:
case POLYGON_CHILDPOOL_SWAP_MATIC_FOR_MATICX_VIA_INSTANT_POOL:
case BSC_STAKEMANAGER_DEPOSIT:
Expand All @@ -21,6 +22,7 @@ void handle_query_contract_id(ethQueryContractID_t *msg) {
break;

case ETHX_REQUEST_WITHDRAW:
case ETHX_REQUEST_WITHDRAW_LEGACY:
case ETH_MATICX_REQUEST_WITHDRAW:
case POLYGON_CHILDPOOL_REQUEST_MATICX_SWAP:
case BSC_STAKEMANAGER_REQUEST_WITHDRAW:
Expand Down
7 changes: 4 additions & 3 deletions src/handle_query_contract_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ static bool set_native_token_stake_ui(ethQueryContractUI_t *msg, context_t *cont
const uint8_t *native_token_amount = msg->pluginSharedRO->txContent->value.value;
uint8_t native_token_amount_size = msg->pluginSharedRO->txContent->value.length;

char ftm_ticker[MAX_TICKER_LEN] = "FTM";
if (memcmp(msg->network_ticker, ftm_ticker, 3) == 0) {
context->ticker = ftm_ticker;
if (memcmp(msg->network_ticker, "FTM", 3) == 0) {
context->ticker = "FTM";
}

// Converts the uint256 number located in `native_token_amount` to its string representation and
Expand Down Expand Up @@ -152,10 +151,12 @@ void handle_query_contract_ui(ethQueryContractUI_t *msg) {
break;

case ETHX_DEPOSIT:
case ETHX_DEPOSIT_LEGACY:
ret = handle_ethx_deposit(msg, context);
break;

case ETHX_REQUEST_WITHDRAW:
case ETHX_REQUEST_WITHDRAW_LEGACY:
ret = handle_ethx_request_withdraw(msg, context);
break;

Expand Down
4 changes: 3 additions & 1 deletion src/staderlabs_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <string.h>

// Number of selectors defined in this plugin. Should match the enum `selector_t`.
#define NUM_SELECTORS 15
#define NUM_SELECTORS 17

// Name of the plugin.
#define PLUGIN_NAME "Staderlabs"
Expand All @@ -28,6 +28,8 @@ typedef enum {
ETHX_DEPOSIT,
ETHX_REQUEST_WITHDRAW,
ETHX_CLAIM,
ETHX_DEPOSIT_LEGACY,
ETHX_REQUEST_WITHDRAW_LEGACY,
} selector_t;

// Enumeration used to parse the smart contract data.
Expand Down
2 changes: 1 addition & 1 deletion tests/build_local_test_elfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
NANOS_SDK=$NANOS_SDK
NANOSP_SDK=$NANOSP_SDK
NANOX_SDK=$NANOX_SDK
APP_ETHEREUM=${APP_ETHEREUM:-"/plugin_dev/app-ethereum"}
APP_ETHEREUM=${APP_ETHEREUM:-"/app/app-ethereum"}

set -e

Expand Down
Loading
Loading