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

Fix Decimals Handling #93

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
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
28 changes: 14 additions & 14 deletions packages/core/src/interfaces/jpyc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ export interface IJPYC {
* @param minter - Minter address
* @returns minter allowance
*/
minterAllowance(params: { minter: Address }): Promise<Uint256>;
minterAllowance(params: { minter: Address }): Promise<number>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

各種 SDK インターフェースの変更が必要になったので、そちらも修正しています。


/**
* Returns total supply of JPYC tokens.
*
* @returns total supply
*/
totalSupply(): Promise<Uint256>;
totalSupply(): Promise<number>;

/**
* Returns balance of an account.
*
* @param account - Account address
* @returns account balance
*/
balanceOf(params: { account: Address }): Promise<Uint256>;
balanceOf(params: { account: Address }): Promise<number>;

/**
* Returns allowance of a spender over owner's tokens (for transferring).
Expand All @@ -46,7 +46,7 @@ export interface IJPYC {
* @param spender - Spender address
* @returns spender allowance
*/
allowance(params: { owner: Address; spender: Address }): Promise<Uint256>;
allowance(params: { owner: Address; spender: Address }): Promise<number>;

/**
* Returns nonce for EIP2612's `permit`.
Expand All @@ -67,7 +67,7 @@ export interface IJPYC {
* @param minterAllowedAmount - Minter allowance
* @returns transaction hash
*/
configureMinter(params: { minter: Address; minterAllowedAmount: Uint256 }): Promise<Hash>;
configureMinter(params: { minter: Address; minterAllowedAmount: number }): Promise<Hash>;

/**
* Mints tokens.
Expand All @@ -76,7 +76,7 @@ export interface IJPYC {
* @param amount - Amount of tokens to mint
* @returns transaction hash
*/
mint(params: { to: Address; amount: Uint256 }): Promise<Hash>;
mint(params: { to: Address; amount: number }): Promise<Hash>;

/**
* Transfers tokens (directly).
Expand All @@ -85,7 +85,7 @@ export interface IJPYC {
* @param value - Amount of tokens to transfer
* @returns transaction hash
*/
transfer(params: { to: Address; value: Uint256 }): Promise<Hash>;
transfer(params: { to: Address; value: number }): Promise<Hash>;

/**
* Transfers tokens (from spender).
Expand All @@ -95,7 +95,7 @@ export interface IJPYC {
* @param value - Amount of tokens to transfer
* @returns transaction hash
*/
transferFrom(params: { from: Address; to: Address; value: Uint256 }): Promise<Hash>;
transferFrom(params: { from: Address; to: Address; value: number }): Promise<Hash>;

/**
* Transfers tokens with authorization.
Expand All @@ -114,7 +114,7 @@ export interface IJPYC {
transferWithAuthorization(params: {
from: Address;
to: Address;
value: Uint256;
value: number;
validAfter: Uint256;
validBefore: Uint256;
nonce: Bytes32;
Expand All @@ -140,7 +140,7 @@ export interface IJPYC {
receiveWithAuthorization(params: {
from: Address;
to: Address;
value: Uint256;
value: number;
validAfter: Uint256;
validBefore: Uint256;
nonce: Bytes32;
Expand Down Expand Up @@ -174,7 +174,7 @@ export interface IJPYC {
* @param value - Amount of allowance
* @returns transaction hash
*/
approve(params: { spender: Address; value: Uint256 }): Promise<Hash>;
approve(params: { spender: Address; value: number }): Promise<Hash>;

/**
* Increases allowance.
Expand All @@ -183,7 +183,7 @@ export interface IJPYC {
* @param increment - Amount of allowance to increase
* @returns transaction hash
*/
increaseAllowance(params: { spender: Address; increment: Uint256 }): Promise<Hash>;
increaseAllowance(params: { spender: Address; increment: number }): Promise<Hash>;

/**
* Decreases allowance.
Expand All @@ -192,7 +192,7 @@ export interface IJPYC {
* @param increment - Amount of allowance to decrease
* @returns transaction hash
*/
decreaseAllowance(params: { spender: Address; decrement: Uint256 }): Promise<Hash>;
decreaseAllowance(params: { spender: Address; decrement: number }): Promise<Hash>;

/**
* Sets allowance of a spender over owner's tokens, given owner's signed approval.
Expand All @@ -209,7 +209,7 @@ export interface IJPYC {
permit(params: {
owner: Address;
spender: Address;
value: Uint256;
value: number;
deadline: Uint256;
v: Uint8;
r: Bytes32;
Expand Down
63 changes: 33 additions & 30 deletions packages/core/src/jpyc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import { getContract, GetContractReturnType, Hash, WalletClient } from 'viem';
import { IJPYC, JPYC_V2_ABI } from './interfaces';
import {
Address,
addDecimals,
Bytes32,
InvalidAddressError,
InvalidTransactionError,
isValidAddress,
LOCAL_PROXY_ADDRESS,
removeDecimals,
toUint256,
V2_PROXY_ADDRESS,
} from './utils';

Expand Down Expand Up @@ -39,42 +42,42 @@ export class JPYC implements IJPYC {
return resp as boolean;
}

async minterAllowance(params: { minter: Address }): Promise<Uint256> {
async minterAllowance(params: { minter: Address }): Promise<number> {
const resp = await this.contract.read.minterAllowance([params.minter]);

return Uint256.from((resp as bigint).toString());
return addDecimals(Uint256.from(resp as string));
}

async totalSupply(): Promise<Uint256> {
async totalSupply(): Promise<number> {
const resp = await this.contract.read.totalSupply();

return Uint256.from((resp as bigint).toString());
return addDecimals(Uint256.from(resp as string));
}

async balanceOf(params: { account: Address }): Promise<Uint256> {
async balanceOf(params: { account: Address }): Promise<number> {
const resp = await this.contract.read.balanceOf([params.account]);

return Uint256.from((resp as bigint).toString());
return addDecimals(Uint256.from(resp as string));
}

async allowance(params: { owner: Address; spender: Address }): Promise<Uint256> {
async allowance(params: { owner: Address; spender: Address }): Promise<number> {
const resp = await this.contract.read.allowance([params.owner, params.spender]);

return Uint256.from((resp as bigint).toString());
return addDecimals(Uint256.from(resp as string));
}

async nonces(params: { owner: Address }): Promise<Uint256> {
const resp = await this.contract.read.nonces([params.owner]);

return Uint256.from((resp as bigint).toString());
return toUint256(resp as bigint);
}

/**
* Regular Functions
* Mutation Functions
*/

async configureMinter(params: { minter: Address; minterAllowedAmount: Uint256 }): Promise<Hash> {
const args = [params.minter, params.minterAllowedAmount];
async configureMinter(params: { minter: Address; minterAllowedAmount: number }): Promise<Hash> {
const args = [params.minter, removeDecimals(params.minterAllowedAmount)];

try {
await this.contract.simulate.configureMinter(args);
Expand All @@ -85,8 +88,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.configureMinter(args);
}

async mint(params: { to: Address; amount: Uint256 }): Promise<Hash> {
const args = [params.to, params.amount];
async mint(params: { to: Address; amount: number }): Promise<Hash> {
const args = [params.to, removeDecimals(params.amount)];

try {
await this.contract.simulate.mint(args);
Expand All @@ -97,8 +100,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.mint(args);
}

async transfer(params: { to: Address; value: Uint256 }): Promise<Hash> {
const args = [params.to, params.value];
async transfer(params: { to: Address; value: number }): Promise<Hash> {
const args = [params.to, removeDecimals(params.value)];

try {
await this.contract.simulate.transfer(args);
Expand All @@ -109,8 +112,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.transfer(args);
}

async transferFrom(params: { from: Address; to: Address; value: Uint256 }): Promise<Hash> {
const args = [params.from, params.to, params.value];
async transferFrom(params: { from: Address; to: Address; value: number }): Promise<Hash> {
const args = [params.from, params.to, removeDecimals(params.value)];

try {
await this.contract.simulate.transferFrom(args);
Expand All @@ -124,7 +127,7 @@ export class JPYC implements IJPYC {
async transferWithAuthorization(params: {
from: Address;
to: Address;
value: Uint256;
value: number;
validAfter: Uint256;
validBefore: Uint256;
nonce: Bytes32;
Expand All @@ -135,7 +138,7 @@ export class JPYC implements IJPYC {
const args = [
params.from,
params.to,
params.value,
removeDecimals(params.value),
params.validAfter,
params.validBefore,
params.nonce,
Expand All @@ -156,7 +159,7 @@ export class JPYC implements IJPYC {
async receiveWithAuthorization(params: {
from: Address;
to: Address;
value: Uint256;
value: number;
validAfter: Uint256;
validBefore: Uint256;
nonce: Bytes32;
Expand All @@ -167,7 +170,7 @@ export class JPYC implements IJPYC {
const args = [
params.from,
params.to,
params.value,
removeDecimals(params.value),
params.validAfter,
params.validBefore,
params.nonce,
Expand Down Expand Up @@ -203,8 +206,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.cancelAuthorization(args);
}

async approve(params: { spender: Address; value: Uint256 }): Promise<Hash> {
const args = [params.spender, params.value];
async approve(params: { spender: Address; value: number }): Promise<Hash> {
const args = [params.spender, removeDecimals(params.value)];

try {
await this.contract.simulate.approve(args);
Expand All @@ -215,8 +218,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.approve(args);
}

async increaseAllowance(params: { spender: Address; increment: Uint256 }): Promise<Hash> {
const args = [params.spender, params.increment];
async increaseAllowance(params: { spender: Address; increment: number }): Promise<Hash> {
const args = [params.spender, removeDecimals(params.increment)];

try {
await this.contract.simulate.increaseAllowance(args);
Expand All @@ -227,8 +230,8 @@ export class JPYC implements IJPYC {
return await this.contract.write.increaseAllowance(args);
}

async decreaseAllowance(params: { spender: Address; decrement: Uint256 }): Promise<Hash> {
const args = [params.spender, params.decrement];
async decreaseAllowance(params: { spender: Address; decrement: number }): Promise<Hash> {
const args = [params.spender, removeDecimals(params.decrement)];

try {
await this.contract.simulate.decreaseAllowance(args);
Expand All @@ -242,7 +245,7 @@ export class JPYC implements IJPYC {
async permit(params: {
owner: Address;
spender: Address;
value: Uint256;
value: number;
deadline: Uint256;
v: Uint8;
r: Bytes32;
Expand All @@ -251,7 +254,7 @@ export class JPYC implements IJPYC {
const args = [
params.owner,
params.spender,
params.value,
removeDecimals(params.value),
params.deadline,
params.v,
params.r,
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './addresses';
export * from './chains';
export * from './errors';
export * from './math';
export * from './types';
33 changes: 33 additions & 0 deletions packages/core/src/utils/math.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Uint256 } from 'soltypes';

import { toUint256, removeDecimals, addDecimals } from './math';

describe('Unit tests of toUint256()', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今回追加した関数のユニットテストも追加しました

test('converts bigint to uint256 value', () => {
const res = toUint256(123456789n);
expect(res).toBeInstanceOf(Uint256);
expect(res.toString()).toStrictEqual('123456789');
});
});

describe('Unit tests of removeDecimals()', () => {
test('removes decimal places from a decimal', () => {
const res = removeDecimals(0.01);
expect(res).toBeInstanceOf(Uint256);
expect(res.toString()).toStrictEqual('10000000000000000');
});

test('removes decimal places from an integer (no decimal places)', () => {
const res = removeDecimals(100);
expect(res).toBeInstanceOf(Uint256);
expect(res.toString()).toStrictEqual('100000000000000000000');
});
});

describe('Unit tests of addDecimals()', () => {
test('adds decimal places to bigint', () => {
const res = addDecimals(Uint256.from('100'));
expect(typeof res).toBe('number');
expect(res).toStrictEqual(0.0000000000000001);
});
});
16 changes: 16 additions & 0 deletions packages/core/src/utils/math.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Uint256 } from 'soltypes';

const TOKEN_DECIMALS = 18;
const DECIMALS_QUANTIFIER = 10 ** TOKEN_DECIMALS;

export const toUint256 = (value: bigint): Uint256 => {
return Uint256.from(value.toString());
};

export const removeDecimals = (value: number): Uint256 => {
return toUint256(BigInt(value * DECIMALS_QUANTIFIER));
};

export const addDecimals = (value: Uint256): number => {
return Number(value.toString()) / DECIMALS_QUANTIFIER;
};
Comment on lines +10 to +16
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decimal 変換処理を行う部分を外部に切り出し、to/from-onChainValue よりもより具体的な関数名に修正しています。
また、それぞれの引数のタイプについても適切なものにしました。