Skip to content

Commit

Permalink
Merge pull request #72 from onomyprotocol/dong/update-psm
Browse files Browse the repository at this point in the history
PSM: Updates psm
  • Loading branch information
DongLieu authored Nov 2, 2024
2 parents 3d45ab9 + cff92b7 commit cda17b1
Show file tree
Hide file tree
Showing 20 changed files with 408 additions and 382 deletions.
4 changes: 4 additions & 0 deletions proto/reserve/psm/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package reserve.psm.v1;
import "amino/amino.proto";
import "gogoproto/gogo.proto";
import "reserve/psm/v1/params.proto";
import "reserve/psm/v1/psm.proto";

option go_package = "github.com/onomyprotocol/reserve/x/psm/types";

Expand All @@ -14,4 +15,7 @@ message GenesisState {
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];

repeated Stablecoin stablecoins = 2
[ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
}
22 changes: 16 additions & 6 deletions proto/reserve/psm/v1/psm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "cosmos/base/v1beta1/coin.proto";
option go_package = "github.com/onomyprotocol/reserve/x/psm/types";

message Stablecoin {
// stablecoin name
string denom = 1;
// limit total stablecoin module support
bytes limit_total = 2 [
Expand All @@ -17,20 +18,29 @@ message Stablecoin {
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
// stablecoin to nomUSD exchange fee, fee_in when 1 stablecoin = 1nomUSD
bytes fee_in = 3 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// nomUSD to stablecoin exchange fee, fee_out when 1 stablecoin = 1nomUSD
bytes fee_out = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// amount of stablecoins locked in exchange for nomUSD
bytes total_stablecoin_lock = 5 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
// maximum fee for when either fee = 0
bytes fee_max_stablecoin = 6 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
}

// message LockCoin {
// string address = 1;
// cosmos.base.v1beta1.Coin coin = 2;
// int64 time = 3;
// }
13 changes: 1 addition & 12 deletions proto/reserve/psm/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,7 @@ message QueryStablecoinRequest {

message QueryStablecoinResponse {
Stablecoin stablecoin = 1 [(gogoproto.nullable) = false];
bytes current_total = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];

bytes swapable_quantity = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "cosmossdk.io/math.Int",
Expand All @@ -69,12 +64,6 @@ message QueryAllStablecoinResponse {

message StablecoinResponse {
Stablecoin stablecoin = 1 [(gogoproto.nullable) = false];
bytes current_total = 2 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
bytes swapable_quantity = 3 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "cosmossdk.io/math.Int",
Expand Down
28 changes: 14 additions & 14 deletions script/psm-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,35 +112,35 @@ sed -i -E "s|persistent_peers = \"\"|persistent_peers = \"$node1@localhost:26656


# # start all three validators
# screen -S onomy1 -t onomy1 -d -m reserved start --home=$HOME/.reserved/validator1
# screen -S onomy2 -t onomy2 -d -m reserved start --home=$HOME/.reserved/validator2
# screen -S onomy3 -t onomy3 -d -m reserved start --home=$HOME/.reserved/validator3
screen -S onomy1 -t onomy1 -d -m reserved start --home=$HOME/.reserved/validator1
screen -S onomy2 -t onomy2 -d -m reserved start --home=$HOME/.reserved/validator2
screen -S onomy3 -t onomy3 -d -m reserved start --home=$HOME/.reserved/validator3

# submit proposal add usdt
# sleep 7
# reserved tx gov submit-proposal ./script/proposal-2.json --home=$HOME/.reserved/validator1 --from validator1 --keyring-backend test --fees 20stake --chain-id testing-1 -y
sleep 7
reserved tx gov submit-proposal ./script/proposal-2.json --home=$HOME/.reserved/validator1 --from validator1 --keyring-backend test --fees 20stake --chain-id testing-1 -y

# # # vote
# sleep 7
reserved tx gov vote 2 yes --from validator1 --keyring-backend test --home ~/.reserved/validator1 --chain-id testing-1 -y --fees 20stake
reserved tx gov vote 2 yes --from validator2 --keyring-backend test --home ~/.reserved/validator2 --chain-id testing-1 -y --fees 20stake
reserved tx gov vote 2 yes --from validator3 --keyring-backend test --home ~/.reserved/validator3 --chain-id testing-1 -y --fees 20stake
sleep 7
reserved tx gov vote 1 yes --from validator1 --keyring-backend test --home ~/.reserved/validator1 --chain-id testing-1 -y --fees 20stake
reserved tx gov vote 1 yes --from validator2 --keyring-backend test --home ~/.reserved/validator2 --chain-id testing-1 -y --fees 20stake
reserved tx gov vote 1 yes --from validator3 --keyring-backend test --home ~/.reserved/validator3 --chain-id testing-1 -y --fees 20stake

# # wait voting_perio=15s
# sleep 15
sleep 15
# echo "========sleep=========="

# # check add usdt, balances
# reserved q psm all-stablecoin
# reserved q bank balances $(reserved keys show validator1 -a --keyring-backend test --home /Users/donglieu/.reserved/validator1)
reserved q bank balances $(reserved keys show validator1 -a --keyring-backend test --home /Users/donglieu/.reserved/validator1)

# # tx swap usdt to nomUSD
# echo "========swap==========="
# reserved tx psm swap-to-nomUSD 100000000000000000000000000000usdt --from validator1 --keyring-backend test --home ~/.reserved/validator1 --chain-id testing-1 -y --fees 20stake
reserved tx psm swap-to-nomUSD 100000000000000000000000usdt --from validator1 --keyring-backend test --home ~/.reserved/validator1 --chain-id testing-1 -y --fees 20stake

# sleep 7
sleep 7
# # Check account after swap
# reserved q bank balances $(reserved keys show validator1 -a --keyring-backend test --home /Users/donglieu/.reserved/validator1)
reserved q bank balances $(reserved keys show validator1 -a --keyring-backend test --home /Users/donglieu/.reserved/validator1)

# # tx swap nomUSD to usdt
# reserved tx psm swap-to-stablecoin usdt 1000nomUSD --from validator1 --keyring-backend test --home ~/.reserved/validator1 --chain-id testing-1 -y --fees 20stake
Expand Down
23 changes: 11 additions & 12 deletions x/psm/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ func (k Keeper) UpdatesStablecoinEpoch(ctx context.Context) error {
}

sc := k.stablecoinUpdate(ctx, *price, red)
err := k.SetStablecoin(ctx, sc)
err := k.Stablecoins.Set(ctx, sc.Denom, sc)
if err != nil {
return false
}
return false
}

return k.IterateStablecoin(ctx, updatePrice)
return k.Stablecoins.Walk(ctx, nil, func(key string, value types.Stablecoin) (stop bool, err error) {
return updatePrice(value), nil
}) //k.IterateStablecoin(ctx, updatePrice)
}

// price is $nomUSD amount to exchange for 1 $stabalecoin
Expand Down Expand Up @@ -65,29 +67,26 @@ func (k Keeper) stablecoinUpdate(ctx context.Context, newPrice math.LegacyDec, s
return stablecoin
}
// fee in anf out < fee_in +fee_out
feeMax, err := k.FeeMaxStablecoin.Get(ctx, stablecoin.Denom)
if err != nil {
panic(err)
}
feeMax := stablecoin.FeeMaxStablecoin

rate := math.LegacyOneDec().Quo(newPrice)
if rate.LT(math.LegacyOneDec()) {
feeOut := math.LegacyMustNewDecFromStr(feeMax).QuoInt64(2)
feeOut := feeMax.QuoInt64(2)
for i := 0; i < int(params.AdjustmentFee); i++ {
feeOut = feeOut.Quo(rate)
}
feeOut = math.LegacyMinDec(feeOut, math.LegacyMustNewDecFromStr(feeMax))
feeIn := math.LegacyMustNewDecFromStr(feeMax).Sub(feeOut)
feeOut = math.LegacyMinDec(feeOut, feeMax)
feeIn := feeMax.Sub(feeOut)

stablecoin.FeeIn = feeIn
stablecoin.FeeOut = feeOut
} else {
feeIn := math.LegacyMustNewDecFromStr(feeMax).QuoInt64(2)
feeIn := feeMax.QuoInt64(2)
for i := 0; i < int(params.AdjustmentFee); i++ {
feeIn = feeIn.Mul(rate)
}
feeIn = math.LegacyMinDec(feeIn, math.LegacyMustNewDecFromStr(feeMax))
feeOut := math.LegacyMustNewDecFromStr(feeMax).Sub(feeIn)
feeIn = math.LegacyMinDec(feeIn, feeMax)
feeOut := feeMax.Sub(feeIn)

stablecoin.FeeIn = feeIn
stablecoin.FeeOut = feeOut
Expand Down
17 changes: 7 additions & 10 deletions x/psm/keeper/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,23 @@ func (s *KeeperTestSuite) TestUpdatesStablecoinEpoch() {

for _, t := range tests {
s.Run(t.name, func() {
sc := types.Stablecoin{
sc := types.GetMsgStablecoin(&types.MsgAddStableCoin{
Denom: usdt,
LimitTotal: limitUSDT,
// Price: t.priceCurrent,
FeeIn: t.feeIn,
FeeOut: t.feeOut,
}
FeeIn: t.feeIn,
FeeOut: t.feeOut,
})
s.mockOracleKeeper.SetPrice(s.Ctx, sc.Denom, t.priceCurrent)
err := s.k.FeeMaxStablecoin.Set(s.Ctx, usdt, t.feeIn.Add(t.feeOut).String())
s.Require().NoError(err)
err = s.k.SetStablecoin(s.Ctx, sc)
err := s.k.Stablecoins.Set(s.Ctx, sc.Denom, sc)
s.Require().NoError(err)

s.mockOracleKeeper.SetPrice(s.Ctx, usdt, t.priceUpdate)

err = s.k.UpdatesStablecoinEpoch(s.Ctx)
s.Require().NoError(err)

scUpdate, found := s.k.GetStablecoin(s.Ctx, usdt)
s.Require().True(found)
scUpdate, err := s.k.Stablecoins.Get(s.Ctx, usdt)
s.Require().NoError(err)
// s.Require().Equal(t.priceUpdate, scUpdate.Price)
s.Require().Equal(t.expectFeeIn.String(), scUpdate.FeeIn.String())
s.Require().Equal(t.expectFeeOut.String(), scUpdate.FeeOut.String())
Expand Down
56 changes: 37 additions & 19 deletions x/psm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"cosmossdk.io/log"
"cosmossdk.io/math"

// "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

Expand All @@ -37,9 +36,7 @@ type (
AccountKeeper types.AccountKeeper
OracleKeeper types.OracleKeeper

// stablecoin / totalStablecoinLock
totalStablecoinLock collections.Map[string, math.Int]
FeeMaxStablecoin collections.Map[string, string]
Stablecoins collections.Map[string, types.Stablecoin]
}
)

Expand Down Expand Up @@ -67,13 +64,11 @@ func NewKeeper(
authority: authority,
// logger: logger,

BankKeeper: bankKeeper,
AccountKeeper: accountKeeper,
OracleKeeper: oracleKeeper,
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
totalStablecoinLock: collections.NewMap(sb, types.KeyTotalStablecoinLock, "total_stablecoin_lock", collections.StringKey, sdk.IntValue),
FeeMaxStablecoin: collections.NewMap(sb, types.KeyFeeMax, "fee_max_stablecoin", collections.StringKey, collections.StringValue),
// this line is used by starport scaffolding # collection/instantiate
BankKeeper: bankKeeper,
AccountKeeper: accountKeeper,
OracleKeeper: oracleKeeper,
Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)),
Stablecoins: collections.NewMap(sb, types.KeyStableCoin, "stablecoins", collections.StringKey, codec.CollValue[types.Stablecoin](cdc)),
}

schema, err := sb.Build()
Expand All @@ -96,14 +91,37 @@ func (k Keeper) Logger() log.Logger {
}

func (k Keeper) TotalStablecoinLock(ctx context.Context, nameStablecoin string) (math.Int, error) {
total := math.ZeroInt()
sc, err := k.Stablecoins.Get(ctx, nameStablecoin)
if err != nil {
return math.Int{}, fmt.Errorf("canot found stablecoin name %s", nameStablecoin)
}

return sc.TotalStablecoinLock, nil
}

func (k Keeper) AddTotalStablecoinLock(ctx context.Context, amountAdd sdk.Coin) error {
sc, err := k.Stablecoins.Get(ctx, amountAdd.Denom)
if err != nil {
return fmt.Errorf("canot found stablecoin name %s", amountAdd.Denom)
}

err := k.totalStablecoinLock.Walk(ctx, nil, func(key string, value math.Int) (stop bool, err error) {
if key == nameStablecoin {
total = total.Add(value)
}
return false, nil
})
sc.TotalStablecoinLock = sc.TotalStablecoinLock.Add(amountAdd.Amount)
if sc.TotalStablecoinLock.GT(sc.LimitTotal) {
return fmt.Errorf("exceed limitTotal stablecoin %s", amountAdd.Denom)
}

return k.Stablecoins.Set(ctx, sc.Denom, sc)
}

return total, err
func (k Keeper) SubTotalStablecoinLock(ctx context.Context, amountSub sdk.Coin) error {
sc, err := k.Stablecoins.Get(ctx, amountSub.Denom)
if err != nil {
return fmt.Errorf("canot found stablecoin name %s", amountSub.Denom)
}

sc.TotalStablecoinLock = sc.TotalStablecoinLock.Sub(amountSub.Amount)
if sc.TotalStablecoinLock.LT(math.ZeroInt()) {
return fmt.Errorf("not enough stablecoins %s to pay", amountSub.Denom)
}
return k.Stablecoins.Set(ctx, sc.Denom, sc)
}
Loading

0 comments on commit cda17b1

Please sign in to comment.