Skip to content

Commit

Permalink
Merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxMustermann2 committed Oct 12, 2024
2 parents 43e637e + 719dbec commit 248a546
Show file tree
Hide file tree
Showing 18 changed files with 204 additions and 287 deletions.
35 changes: 28 additions & 7 deletions precompiles/avs/avs_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package avs_test

import (
"cosmossdk.io/math"
assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types"
avskeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper"
"github.com/ExocoreNetwork/exocore/x/avs/types"
"math/big"
"time"

sdkmath "cosmossdk.io/math"
assetstype "github.com/ExocoreNetwork/exocore/x/assets/types"
operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper"

"github.com/ExocoreNetwork/exocore/app"
Expand Down Expand Up @@ -433,17 +436,26 @@ func (suite *AVSManagerPrecompileSuite) TestUpdateAVS() {

func (suite *AVSManagerPrecompileSuite) TestRegisterOperatorToAVS() {
// from := s.Address
operatorAddress := sdk.AccAddress(suite.Address.Bytes()).String()
operatorAddress := sdk.AccAddress(suite.Address.Bytes())

registerOperator := func() {
registerReq := &operatortypes.RegisterOperatorReq{
FromAddress: operatorAddress,
FromAddress: operatorAddress.String(),
Info: &operatortypes.OperatorInfo{
EarningsAddr: operatorAddress,
EarningsAddr: operatorAddress.String(),
},
}
_, err := suite.OperatorMsgServer.RegisterOperator(sdk.WrapSDKContext(suite.Ctx), registerReq)
suite.NoError(err)
asset := suite.Assets[0]
_, assetID := assetstypes.GetStakerIDAndAssetIDFromStr(asset.LayerZeroChainID, "", asset.Address)
selfDelegateAmount := big.NewInt(10)
minPrecisionSelfDelegateAmount := big.NewInt(0).Mul(selfDelegateAmount, big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(asset.Decimals)), nil))
err = suite.App.AssetsKeeper.UpdateOperatorAssetState(suite.Ctx, operatorAddress, assetID, assetstypes.DeltaOperatorSingleAsset{
TotalAmount: math.NewIntFromBigInt(minPrecisionSelfDelegateAmount),
TotalShare: math.LegacyNewDecFromBigInt(minPrecisionSelfDelegateAmount),
OperatorShare: math.LegacyNewDecFromBigInt(minPrecisionSelfDelegateAmount),
})
}
commonMalleate := func() (common.Address, []byte) {
input, err := suite.precompile.Pack(
Expand All @@ -469,7 +481,16 @@ func (suite *AVSManagerPrecompileSuite) TestRegisterOperatorToAVS() {
malleate: func() (common.Address, []byte) {
suite.TestRegisterAVS()
registerOperator()
return commonMalleate()
avsAddr, intput := commonMalleate()
asset := suite.Assets[0]
_, defaultAssetID := assetstypes.GetStakerIDAndAssetIDFromStr(asset.LayerZeroChainID, "", asset.Address)
err = suite.App.AVSManagerKeeper.UpdateAVSInfo(suite.Ctx, &types.AVSRegisterOrDeregisterParams{
Action: avskeeper.UpdateAction,
AvsAddress: avsAddr.String(),
AssetID: []string{defaultAssetID},
})
suite.NoError(err)
return avsAddr, intput
},
readOnly: false,
expPass: true,
Expand Down Expand Up @@ -649,7 +670,7 @@ func (suite *AVSManagerPrecompileSuite) TestRunRegTaskInfo() {
suite.prepare()
// register the new token
usdcAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48")
usdcClientChainAsset := assetstype.AssetInfo{
usdcClientChainAsset := assetstypes.AssetInfo{
Name: "USD coin",
Symbol: "USDC",
Address: usdcAddr.String(),
Expand All @@ -659,7 +680,7 @@ func (suite *AVSManagerPrecompileSuite) TestRunRegTaskInfo() {
}
err := suite.App.AssetsKeeper.SetStakingAssetInfo(
suite.Ctx,
&assetstype.StakingAssetInfo{
&assetstypes.StakingAssetInfo{
AssetBasicInfo: usdcClientChainAsset,
StakingTotalAmount: sdkmath.NewInt(0),
},
Expand Down
6 changes: 4 additions & 2 deletions x/assets/keeper/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ type DepositWithdrawParams struct {
// PerformDepositOrWithdraw the assets precompile contract will call this function to update asset state
// when there is a deposit or withdraw.
func (k Keeper) PerformDepositOrWithdraw(ctx sdk.Context, params *DepositWithdrawParams) error {
// check params parameter before executing deposit operation
// check params parameter before executing operation
if params.OpAmount.IsNegative() {
return assetstypes.ErrInvalidDepositAmount.Wrapf("negative deposit amount:%s", params.OpAmount)
return assetstypes.ErrInvalidAmount.Wrapf(
"negative amount:%s", params.OpAmount,
)
}
stakerID, assetID := assetstypes.GetStakerIDAndAssetID(params.ClientChainLzID, params.StakerAddress, params.AssetsAddress)
if !k.IsStakingAsset(ctx, assetID) {
Expand Down
4 changes: 2 additions & 2 deletions x/assets/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ var (
"the input parameter is invalid",
)

ErrInvalidDepositAmount = errorsmod.Register(
ErrInvalidAmount = errorsmod.Register(
ModuleName, 17,
"the deposit amount is invalid")
"the amount is invalid")

ErrInvalidOperationType = errorsmod.Register(
ModuleName, 18,
Expand Down
13 changes: 13 additions & 0 deletions x/avs/keeper/avs_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package keeper_test

import (
"cosmossdk.io/math"
assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types"
"math/big"
"time"

avstypes "github.com/ExocoreNetwork/exocore/x/avs/keeper"
Expand Down Expand Up @@ -154,6 +157,16 @@ func (suite *AVSTestSuite) TestUpdateAVSInfoWithOperator_Register() {
suite.NoError(err)
suite.TestAVS() // registers the AVS

asset := suite.Assets[0]
_, assetID := assetstypes.GetStakerIDAndAssetIDFromStr(asset.LayerZeroChainID, "", asset.Address)
selfDelegateAmount := big.NewInt(10)
minPrecisionSelfDelegateAmount := big.NewInt(0).Mul(selfDelegateAmount, big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(asset.Decimals)), nil))
err = suite.App.AssetsKeeper.UpdateOperatorAssetState(suite.Ctx, opAccAddr, assetID, assetstypes.DeltaOperatorSingleAsset{
TotalAmount: math.NewIntFromBigInt(minPrecisionSelfDelegateAmount),
TotalShare: math.LegacyNewDecFromBigInt(minPrecisionSelfDelegateAmount),
OperatorShare: math.LegacyNewDecFromBigInt(minPrecisionSelfDelegateAmount),
})
suite.NoError(err)
err = suite.App.AVSManagerKeeper.OperatorOptAction(suite.Ctx, operatorParams)
suite.NoError(err)
}
9 changes: 1 addition & 8 deletions x/avs/keeper/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import (
sdkmath "cosmossdk.io/math"
blscommon "github.com/prysmaticlabs/prysm/v4/crypto/bls/common"

"github.com/ExocoreNetwork/exocore/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/evmos/evmos/v16/app"
utiltx "github.com/evmos/evmos/v16/testutil/tx"
evm "github.com/evmos/evmos/v16/x/evm/types"

"github.com/ExocoreNetwork/exocore/testutil"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/suite"
Expand All @@ -34,10 +31,6 @@ type AVSTestSuite struct {
delegationAmount sdkmath.Int
updatedAmountForOptIn sdkmath.Int

ctx sdk.Context
app *app.Evmos
queryClientEvm evm.QueryClient
consAddress sdk.ConsAddress
avsAddress common.Address
taskAddress common.Address
taskId uint64
Expand Down
8 changes: 6 additions & 2 deletions x/avs/keeper/submit_task_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"github.com/ethereum/go-ethereum/common/math"
"math/big"
"strconv"
"time"
Expand Down Expand Up @@ -149,10 +150,13 @@ func (suite *AVSTestSuite) prepareTaskInfo() {

func (suite *AVSTestSuite) prepare() {
usdtAddress := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
depositAmount := sdkmath.NewInt(100)
delegationAmount := sdkmath.NewInt(50)
decimal := int64(6)
depositAmount := sdkmath.NewInt(100).Mul(sdkmath.NewIntFromBigInt(math.BigPow(10, decimal)))
delegationAmount := sdkmath.NewInt(50).Mul(sdkmath.NewIntFromBigInt(math.BigPow(10, decimal)))
suite.prepareOperator()
suite.prepareDeposit(usdtAddress, depositAmount)
err := suite.App.DelegationKeeper.AssociateOperatorWithStaker(suite.Ctx, suite.clientChainLzID, suite.operatorAddr, suite.Address[:])
suite.NoError(err)
suite.prepareDelegation(true, usdtAddress, delegationAmount)
suite.prepareAvs([]string{"0xdac17f958d2ee523a2206206994597c13d831ec7_0x65"})
suite.prepareOptIn()
Expand Down
3 changes: 2 additions & 1 deletion x/dogfood/keeper/impl_sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ func (k Keeper) Delegation(
// This interface is only used for unjail to retrieve the self delegation value,
// so the delegator and validator are the same.
operator := delegator
operatorUSDValues, err := k.operatorKeeper.GetOrCalculateOperatorUSDValues(ctx, operator, avstypes.ChainIDWithoutRevision(ctx.ChainID()))
avsAddr := avstypes.GenerateAVSAddr(avstypes.ChainIDWithoutRevision(ctx.ChainID()))
operatorUSDValues, err := k.operatorKeeper.GetOrCalculateOperatorUSDValues(ctx, operator, avsAddr)
if err != nil {
k.Logger(ctx).Error("Delegation: failed to get or calculate the operator USD values", "operator", operator.String(), "chainID", ctx.ChainID(), "error", err)
return nil
Expand Down
9 changes: 8 additions & 1 deletion x/dogfood/keeper/opt_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (suite *KeeperTestSuite) TestBasicOperations() {
AvsAddress: avsAddress,
PublicKeyJSON: key.ToJSON(),
})
suite.NoError(err)
suite.Error(err)
// opted in but not enough self-delegation
suite.CheckLengthOfValidatorUpdates(0, nil, "opt in but no delegation")

Expand Down Expand Up @@ -114,6 +114,13 @@ func (suite *KeeperTestSuite) TestBasicOperations() {
assetDecimals,
0, // price decimals
)
// opt in again when the self delegation meet the requirement
_, err = suite.OperatorMsgServer.OptIntoAVS(sdk.WrapSDKContext(suite.Ctx), &operatortypes.OptIntoAVSReq{
FromAddress: operatorAddressString,
AvsAddress: avsAddress,
PublicKeyJSON: key.ToJSON(),
})
suite.NoError(err)
suite.CheckLengthOfValidatorUpdates(
1, []int64{totalAmountInUSD.TruncateInt64()}, "delegate above min",
)
Expand Down
10 changes: 5 additions & 5 deletions x/evm/keeper/precompiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
blsPrecompile "github.com/ExocoreNetwork/exocore/precompiles/bls"
delegationprecompile "github.com/ExocoreNetwork/exocore/precompiles/delegation"
rewardPrecompile "github.com/ExocoreNetwork/exocore/precompiles/reward"
slashPrecompile "github.com/ExocoreNetwork/exocore/precompiles/slash"
stakingStateKeeper "github.com/ExocoreNetwork/exocore/x/assets/keeper"
avsManagerKeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper"
delegationKeeper "github.com/ExocoreNetwork/exocore/x/delegation/keeper"
Expand All @@ -37,7 +36,7 @@ func AvailablePrecompiles(
_ channelkeeper.Keeper,
delegationKeeper delegationKeeper.Keeper,
assetskeeper stakingStateKeeper.Keeper,
slashKeeper exoslashKeeper.Keeper,
_ exoslashKeeper.Keeper,
rewardKeeper rewardKeeper.Keeper,
avsManagerKeeper avsManagerKeeper.Keeper,
) map[common.Address]vm.PrecompiledContract {
Expand Down Expand Up @@ -69,11 +68,12 @@ func AvailablePrecompiles(
panic(fmt.Errorf("failed to load delegation precompile: %w", err))
}

slashPrecompile, err := slashPrecompile.NewPrecompile(
// The slash precompile is deprecated, but I have only commented out this code to facilitate future refactoring.
/* slashPrecompile, err := slashPrecompile.NewPrecompile(
assetskeeper,
slashKeeper,
authzKeeper,
)
)*/
if err != nil {
panic(fmt.Errorf("failed to load slash precompile: %w", err))
}
Expand All @@ -93,7 +93,7 @@ func AvailablePrecompiles(
if err != nil {
panic(fmt.Errorf("failed to load bls precompile: %v", err))
}
precompiles[slashPrecompile.Address()] = slashPrecompile
// precompiles[slashPrecompile.Address()] = slashPrecompile
precompiles[rewardPrecompile.Address()] = rewardPrecompile
precompiles[assetsPrecompile.Address()] = assetsPrecompile
precompiles[delegationPrecompile.Address()] = delegationPrecompile
Expand Down
2 changes: 1 addition & 1 deletion x/evm/types/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
"0x0000000000000000000000000000000000000804", // assets precompile
"0x0000000000000000000000000000000000000805", // delegation precompile
"0x0000000000000000000000000000000000000806", // reward precompile
"0x0000000000000000000000000000000000000807", // slash precompile
// "0x0000000000000000000000000000000000000807", // slash precompile
// 0x0000000000000000000000000000000000000808 withdraw precompile has been merged to assets.
// the function has been merged to the assets precompile
"0x0000000000000000000000000000000000000809", // bls precompile
Expand Down
9 changes: 8 additions & 1 deletion x/feedistribution/keeper/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (suite *KeeperTestSuite) prepare() {
AvsAddress: avsAddress,
PublicKeyJSON: key.ToJSON(),
})
suite.NoError(err)
suite.Error(err)
// opted in but not enough self-delegation
suite.CheckLengthOfValidatorUpdates(0, nil, "opt in but no delegation")

Expand Down Expand Up @@ -157,6 +157,13 @@ func (suite *KeeperTestSuite) prepare() {
assetDecimals,
0, // price decimals
)
// Opt in again once the self-delegation requirement is met.
_, err = suite.OperatorMsgServer.OptIntoAVS(sdk.WrapSDKContext(suite.Ctx), &operatortypes.OptIntoAVSReq{
FromAddress: operatorAddressString,
AvsAddress: avsAddress,
PublicKeyJSON: key.ToJSON(),
})
suite.NoError(err)
suite.CheckLengthOfValidatorUpdates(
1, []int64{totalAmountInUSD.TruncateInt64()}, "delegate above min",
)
Expand Down
22 changes: 11 additions & 11 deletions x/operator/keeper/consensus_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,26 +368,26 @@ func (k Keeper) GetActiveOperatorsForChainID(
// ValidatorByConsAddrForChainID returns a stakingtypes.ValidatorI for the given consensus
// address and chain id.
func (k Keeper) ValidatorByConsAddrForChainID(
ctx sdk.Context, consAddr sdk.ConsAddress, chainID string,
ctx sdk.Context, consAddr sdk.ConsAddress, chainIDWithoutRevision string,
) (stakingtypes.Validator, bool) {
isAvs, avsAddrStr := k.avsKeeper.IsAVSByChainID(ctx, chainID)
isAvs, avsAddrStr := k.avsKeeper.IsAVSByChainID(ctx, chainIDWithoutRevision)
if !isAvs {
ctx.Logger().Error("ValidatorByConsAddrForChainID the chainID is not supported by AVS", "chainID", chainID)
ctx.Logger().Error("ValidatorByConsAddrForChainID the chainIDWithoutRevision is not supported by AVS", "chainIDWithoutRevision", chainIDWithoutRevision)
return stakingtypes.Validator{}, false
}
// this value is stored using chainID + consAddr and only deleted when
// this value is stored using chainIDWithoutRevision + consAddr and only deleted when
// advised by the dogfood module to delete. hence, even if the consensus key
// changes, this lookup is available.
found, operatorAddr := k.GetOperatorAddressForChainIDAndConsAddr(
ctx, chainID, consAddr,
ctx, chainIDWithoutRevision, consAddr,
)
if !found {
ctx.Logger().Error("ValidatorByConsAddrForChainID the operator isn't found by the chainID and consensus address", "consAddress", consAddr, "chainID", chainID)
ctx.Logger().Error("ValidatorByConsAddrForChainID the operator isn't found by the chainIDWithoutRevision and consensus address", "consAddress", consAddr, "chainIDWithoutRevision", chainIDWithoutRevision)
return stakingtypes.Validator{}, false
}
found, wrappedKey, err := k.GetOperatorConsKeyForChainID(ctx, operatorAddr, chainID)
found, wrappedKey, err := k.GetOperatorConsKeyForChainID(ctx, operatorAddr, chainIDWithoutRevision)
if !found || err != nil {
ctx.Logger().Error("ValidatorByConsAddrForChainID the consensus key isn't found by the chainID and operator address", "operatorAddr", operatorAddr, "chainID", chainID, "err", err)
ctx.Logger().Error("ValidatorByConsAddrForChainID the consensus key isn't found by the chainIDWithoutRevision and operator address", "operatorAddr", operatorAddr, "chainIDWithoutRevision", chainIDWithoutRevision, "err", err)
return stakingtypes.Validator{}, false
}
// since we are sending the address, we have to send the consensus key as well.
Expand All @@ -400,7 +400,7 @@ func (k Keeper) ValidatorByConsAddrForChainID(
ctx.Logger().Error("ValidatorByConsAddrForChainID new validator error", "err", err)
return stakingtypes.Validator{}, false
}
val.Jailed = k.IsOperatorJailedForChainID(ctx, consAddr, chainID)
val.Jailed = k.IsOperatorJailedForChainID(ctx, consAddr, chainIDWithoutRevision)

// set the tokens, delegated shares and minimum self delegation for unjail
minSelfDelegation, err := k.avsKeeper.GetAVSMinimumSelfDelegation(ctx, avsAddrStr)
Expand All @@ -413,9 +413,9 @@ func (k Keeper) ValidatorByConsAddrForChainID(
// get opted usd values, then use the total usd value as the virtual tokens and shares
// we use USD to simulate the staking token for the cosmos-SDK because the Exocore is
// a multi-token staking system. The tokens and shares are always balanced.
operatorUSDValues, err := k.GetOrCalculateOperatorUSDValues(ctx, operatorAddr, chainID)
operatorUSDValues, err := k.GetOrCalculateOperatorUSDValues(ctx, operatorAddr, avsAddrStr)
if err != nil {
ctx.Logger().Error("ValidatorByConsAddrForChainID get or calculate the operator USD values error", "operatorAddr", operatorAddr, "chainID", chainID, "err", err)
ctx.Logger().Error("ValidatorByConsAddrForChainID get or calculate the operator USD values error", "operatorAddr", operatorAddr, "chainIDWithoutRevision", chainIDWithoutRevision, "err", err)
return stakingtypes.Validator{}, false
}
power := operatorUSDValues.TotalUSDValue.TruncateInt64()
Expand Down
16 changes: 15 additions & 1 deletion x/operator/keeper/opt.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ func (k *Keeper) OptIn(
if k.IsOptedIn(ctx, operatorAddress.String(), avsAddr) {
return types.ErrAlreadyOptedIn
}
// Check if the USD value of the operator is greater than or equal to the self-delegation
// configured by the AVS. This is used to prevent a DDOS attack from zero-USD value opting in.
operatorUSDValues, err := k.GetOrCalculateOperatorUSDValues(ctx, operatorAddress, avsAddr)
if err != nil {
return errorsmod.Wrapf(err, "OptIn: error when calculating operator USD value, operator:%s avsAddr:%s", operatorAddress.String(), avsAddr)
}
minSelfDelegation, err := k.avsKeeper.GetAVSMinimumSelfDelegation(ctx, avsAddr)
if err != nil {
return errorsmod.Wrapf(err, "OptIn: error when getting minimum self delegation of AVS, avsAddr:%s", avsAddr)
}
if operatorUSDValues.SelfUSDValue.LT(minSelfDelegation) {
return errorsmod.Wrapf(types.ErrMinDelegationNotMet, "operator:%s avs:%s selfUSDValue:%s minSelfDelegation:%s", operatorAddress.String(), avsAddr, operatorUSDValues.SelfUSDValue, minSelfDelegation)
}

// do not allow frozen operators to do anything meaningful
if k.slashKeeper.IsOperatorFrozen(ctx, operatorAddress) {
return delegationtypes.ErrOperatorIsFrozen
Expand All @@ -42,7 +56,7 @@ func (k *Keeper) OptIn(
// but the actual voting power calculation and update will be performed at the
// end of epoch of the AVS. So there isn't any reward in the opted-in epoch for the
// operator
err := k.InitOperatorUSDValue(ctx, avsAddr, operatorAddress.String())
err = k.InitOperatorUSDValue(ctx, avsAddr, operatorAddress.String())
if err != nil {
return err
}
Expand Down
8 changes: 5 additions & 3 deletions x/operator/keeper/slash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ func (suite *OperatorTestSuite) TestSlashWithInfractionReason() {
suite.prepareOperator()
usdtAddress := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
assetDecimal := 6
depositAmount := sdkmath.NewIntWithDecimal(100, assetDecimal)
depositAmount := sdkmath.NewIntWithDecimal(200, assetDecimal)
suite.prepareDeposit(usdtAddress, depositAmount)
delegationAmount := sdkmath.NewIntWithDecimal(50, assetDecimal)
delegationAmount := sdkmath.NewIntWithDecimal(100, assetDecimal)
suite.prepareDelegation(true, suite.assetAddr, delegationAmount)
err := suite.App.DelegationKeeper.AssociateOperatorWithStaker(suite.Ctx, suite.clientChainLzID, suite.operatorAddr, suite.Address[:])
suite.NoError(err)

// opt into the AVS
avsAddr := avstypes.GenerateAVSAddr(avstypes.ChainIDWithoutRevision(suite.Ctx.ChainID()))
err := suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr)
err = suite.App.OperatorKeeper.OptIn(suite.Ctx, suite.operatorAddr, avsAddr)
suite.NoError(err)
// call the EndBlock to update the voting power
suite.CommitAfter(time.Hour*24 + time.Nanosecond)
Expand Down
Loading

0 comments on commit 248a546

Please sign in to comment.