Skip to content

Commit

Permalink
Merge branch 'iliad' into feat/add-unjail-cli-subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
leeren authored Oct 4, 2024
2 parents c8517a7 + 9555cc3 commit 943ffbd
Show file tree
Hide file tree
Showing 17 changed files with 226 additions and 66 deletions.
2 changes: 2 additions & 0 deletions client/app/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (

"github.com/piplabs/story/client/app/upgrades"
"github.com/piplabs/story/client/app/upgrades/v0_10_0"
"github.com/piplabs/story/client/app/upgrades/v0_11_0"
)

var (
// `Upgrades` defines the upgrade handlers and store loaders for the application.
// New upgrades should be added to this slice after they are implemented.
Upgrades = []upgrades.Upgrade{
v0_10_0.Upgrade,
v0_11_0.Upgrade,
}
// Forks are for hard forks that breaks backward compatibility.
Forks = []upgrades.Fork{}
Expand Down
16 changes: 16 additions & 0 deletions client/app/upgrades/v0_11_0/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//nolint:revive,stylecheck // version underscores
package v0_11_0

import (
storetypes "cosmossdk.io/store/types"

"github.com/piplabs/story/client/app/upgrades"
)

const UpgradeName = "v0.11.0"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: storetypes.StoreUpgrades{},
}
33 changes: 33 additions & 0 deletions client/app/upgrades/v0_11_0/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//nolint:revive,stylecheck // version underscores
package v0_11_0

import (
"context"

upgradetypes "cosmossdk.io/x/upgrade/types"

"github.com/cosmos/cosmos-sdk/types/module"

"github.com/piplabs/story/client/app/keepers"
"github.com/piplabs/story/lib/errors"
clog "github.com/piplabs/story/lib/log"
)

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
keepers *keepers.Keepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
clog.Info(ctx, "Starting module migrations...")

vm, err := mm.RunMigrations(ctx, configurator, vm)
if err != nil {
return vm, errors.Wrap(err, "run migrations")
}

clog.Info(ctx, "Upgrade v0.11.0 complete")

return vm, nil
}
}
2 changes: 1 addition & 1 deletion client/genutil/evm/predeploys/predeploys.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (

// IP Token Predeploys.
IPTokenStaking = "0xcccccc0000000000000000000000000000000001"
IPTokenSlashing = "0xcccccc0000000000000000000000000000000002"
IPTokenSlashing = "0xa39241Eb9Ff830178339D1E6aD38EfB160Ee9ab1"
UpgradeEntrypoint = "0xcccccc0000000000000000000000000000000003"

Secp256k1 = "0x00000000000000000000000000000000000256f1"
Expand Down
32 changes: 28 additions & 4 deletions client/x/evmstaking/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,39 @@ func (k *Keeper) EndBlock(ctx context.Context) (abci.ValidatorUpdates, error) {
}

for _, entry := range unbondedEntries {
delegatorAddr, err := k.authKeeper.AddressCodec().StringToBytes(entry.delegatorAddress)
if err != nil {
return nil, errors.Wrap(err, "delegator address from bech32")
}

spendableAmount := k.bankKeeper.SpendableCoin(ctx, delegatorAddr, sdk.DefaultBondDenom).Amount
if spendableAmount.IsZero() {
log.Warn(ctx, "No spendable coins for undelegation",
errors.New("no spendable coins for undelegation"),
"delegator", entry.delegatorAddress,
"validator", entry.validatorAddress,
"original_amount", entry.amount.String())

continue
}

// If the requested undelegation amount is greater than the spendable amount, set the real undelegation amount to
// the total spendable amount.
if entry.amount.GT(spendableAmount) {
entry.amount = spendableAmount
log.Warn(ctx, "Spendable amount is less than the requested undelegation amount",
errors.New("spendable amount is less than the requested undelegation amount"),
"delegator", entry.delegatorAddress,
"validator", entry.validatorAddress,
"requested_amount", entry.amount.String(),
"spendable_amount", spendableAmount.String())
}

log.Debug(ctx, "Adding undelegation to withdrawal queue",
"delegator", entry.delegatorAddress,
"validator", entry.validatorAddress,
"amount", entry.amount.String())

delegatorAddr, err := k.authKeeper.AddressCodec().StringToBytes(entry.delegatorAddress)
if err != nil {
return nil, errors.Wrap(err, "delegator address from bech32")
}
// Burn tokens from the delegator
_, coins := IPTokenToBondCoin(entry.amount.BigInt())
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, delegatorAddr, types.ModuleName, coins)
Expand Down
8 changes: 8 additions & 0 deletions client/x/evmstaking/keeper/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"testing"
"time"

sdkmath "cosmossdk.io/math"

abcitypes "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
dtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
Expand Down Expand Up @@ -245,6 +247,7 @@ func (s *TestSuite) TestEndBlock() {
// Mock staking.EndBlocker
s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil)
// Mock evmstaking.EndBlocker
s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(10)))
s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(errors.New("failed to send coins to module"))

return nil, []abcitypes.ValidatorUpdate{
Expand All @@ -271,6 +274,7 @@ func (s *TestSuite) TestEndBlock() {
// Mock staking.EndBlocker
s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil)
// Mock evmstaking.EndBlocker
s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(10)))
s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(nil)
s.BankKeeper.EXPECT().BurnCoins(gomock.Any(), types.ModuleName, gomock.Any()).Return(errors.New("failed to burn coins"))

Expand Down Expand Up @@ -363,6 +367,7 @@ func compareValUpdates(t *testing.T, expected, actual abcitypes.ValidatorUpdates

// setupMaturedUnbonding creates matured unbondings for testing.
func (s *TestSuite) setupMatureUnbondingDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt string, duration time.Duration) {
require := s.Require()
pastHeader := ctx.BlockHeader()
pastHeader.Time = pastHeader.Time.Add(-duration).Add(-time.Minute)
pastCtx := ctx.WithBlockHeader(pastHeader)
Expand All @@ -372,6 +377,9 @@ func (s *TestSuite) setupMatureUnbondingDelegation(ctx sdk.Context, delAddr sdk.
// Mock staking.EndBlocker
s.BankKeeper.EXPECT().UndelegateCoinsFromModuleToAccount(gomock.Any(), stypes.NotBondedPoolName, delAddr, gomock.Any()).Return(nil)
// Mock evmstaking.EndBlocker
amtInt, ok := sdkmath.NewIntFromString(amt)
require.True(ok)
s.BankKeeper.EXPECT().SpendableCoin(gomock.Any(), delAddr, sdk.DefaultBondDenom).Return(sdk.NewCoin(sdk.DefaultBondDenom, amtInt))
s.BankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), delAddr, types.ModuleName, gomock.Any()).Return(nil)
s.BankKeeper.EXPECT().BurnCoins(gomock.Any(), types.ModuleName, gomock.Any()).Return(nil)
}
14 changes: 14 additions & 0 deletions client/x/evmstaking/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/x/evmstaking/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type BankKeeper interface {
GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins
LockedCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins
SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins
SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
GetSupply(ctx context.Context, denom string) sdk.Coin
SendCoinsFromModuleToModule(ctx context.Context, senderPool, recipientPool string, amt sdk.Coins) error
}
Expand Down
1 change: 1 addition & 0 deletions contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"dependencies": {
"@openzeppelin/contracts": "5.0.2",
"@openzeppelin/contracts-upgradeable": "5.0.2",
"solady": "^0.0.246",
"solmate": "^6.2.0"
}
}
8 changes: 8 additions & 0 deletions contracts/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions contracts/script/DeployCore.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ contract DeployCore is Script {
UpgradeEntrypoint upgradeEntrypoint = UpgradeEntrypoint(address(new ERC1967Proxy(impl, "")));
upgradeEntrypoint.initialize(protocolAccessManagerAddr);

vm.stopBroadcast();

console2.log("IPTokenStaking deployed at:", address(ipTokenStaking));
console2.log("IPTokenSlashing deployed at:", address(ipTokenSlashing));
console2.log("UpgradeEntrypoint deployed at:", address(upgradeEntrypoint));

vm.stopBroadcast();
}
}
72 changes: 72 additions & 0 deletions contracts/script/DeployIPTokenSlashing.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.23;
/* solhint-disable no-console */
/* solhint-disable max-line-length */

import { Script } from "forge-std/Script.sol";
import { console2 } from "forge-std/console2.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

import { IPTokenSlashing } from "../src/protocol/IPTokenSlashing.sol";
import { ICreate3Deployer } from "../src/deploy/ICreate3Deployer.sol";

/**
* @title DeployIPTokenSlashing
* @dev A script to deploy IPTokenSlashing for Illiad
*/
contract DeployIPTokenSlashing is Script {
// To run the script:
// - Dry run
// forge script script/DeployIPTokenSlashing.s.sol --fork-url <fork-url>
//
// - Deploy (OK for devnet)
// forge script script/DeployIPTokenSlashing.s.sol --fork-url <fork-url> --broadcast
//
// - Deploy and Verify (for testnet)
// forge script script/DeployIPTokenSlashing.s.sol --fork-url https://testnet.storyrpc.io --broadcast --verify --verifier blockscout --verifier-url https://testnet.storyscan.xyz/api\?
function run() public {
// Read env for admin address
address protocolAccessManagerAddr = vm.envAddress("ADMIN_ADDRESS");
require(protocolAccessManagerAddr != address(0), "address not set");
// Read env for deployer private key
uint256 deployerKey = vm.envUint("IPTOKENSTAKING_DEPLOYER_KEY");
address deployer = vm.addr(deployerKey);
require(deployer != protocolAccessManagerAddr, "Deployer wallet can't be admin address");
console2.log("deployer", deployer);
vm.startBroadcast(deployerKey);

ICreate3Deployer c3Deployer = ICreate3Deployer(0x384a891dFDE8180b054f04D66379f16B7a678Ad6);
console2.log("Create3 deployer:", address(c3Deployer));

address ipTokenStaking = 0xCCcCcC0000000000000000000000000000000001;

address impl = address(new IPTokenSlashing(ipTokenStaking));
bytes memory initializationData = abi.encodeCall(
IPTokenSlashing.initialize,
(
protocolAccessManagerAddr,
1 ether // unjailFee
)
);
bytes memory creationCode =
abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(impl, initializationData));

bytes32 salt = keccak256(abi.encode("STORY", type(IPTokenSlashing).name));
address predicted = c3Deployer.getDeployed(salt);
console2.log("IPTokenSlashing will be deployed at:", predicted);
IPTokenSlashing ipTokenSlashing = IPTokenSlashing(c3Deployer.deploy(salt, creationCode));

console2.log("IP_TOKEN_STAKING", address(ipTokenSlashing.IP_TOKEN_STAKING()));
console2.log("owner:", ipTokenSlashing.owner());
console2.log("unjailFee:", ipTokenSlashing.unjailFee());

if (address(ipTokenSlashing) != predicted) {
revert("IPTokenSlashing mismatch");
}
console2.log("IPTokenSlashing deployed at:", address(ipTokenSlashing));

vm.stopBroadcast();
}


}
40 changes: 0 additions & 40 deletions contracts/src/deploy/Create3.sol

This file was deleted.

15 changes: 15 additions & 0 deletions contracts/src/deploy/ICreate3Deployer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

interface ICreate3Deployer {
/// @notice Deploys a contract using CREATE3
/// @param salt The salt to use for deployment
/// @param creationCode The contract creation code
/// @return deployed The address of the deployed contract
function deploy(bytes32 salt, bytes calldata creationCode) external payable returns (address);

/// @notice Predicts the address of a deployed contract
/// @param salt The salt to use for deployment
/// @return deployed The address of the contract that will be deployed
function getDeployed(bytes32 salt) external view returns (address);
}
13 changes: 3 additions & 10 deletions contracts/test/deploy/Create3.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,17 @@ contract Create3Test is Test {
bytes32 salt = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;
bytes memory creationCode = type(Create3).creationCode;
address deployed = create3.deploy(salt, creationCode);
address expected = create3.getDeployed(address(this), salt);
address expected = create3.getDeployed(salt);
assertEq(deployed, expected);

// Network shall generate the same address for the same deployer and salt.
vm.expectRevert("DEPLOYMENT_FAILED");
vm.expectRevert();
deployed = create3.deploy(salt, creationCode);

// Network shall generate different addresses for different deployers.
address otherAddr = address(0xf398C12A45Bc409b6C652E25bb0a3e702492A4ab);
vm.prank(otherAddr);
deployed = create3.deploy(salt, creationCode);
expected = create3.getDeployed(otherAddr, salt);
assertEq(deployed, expected);

// Network shall generate different addresses for different salts.
bytes32 otherSalt = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890fedcba;
deployed = create3.deploy(otherSalt, creationCode);
expected = create3.getDeployed(address(this), otherSalt);
expected = create3.getDeployed(otherSalt);
assertEq(deployed, expected);
}
}
Loading

0 comments on commit 943ffbd

Please sign in to comment.