Explorar el Código

accountant: address review comments for modify governance vaa

Conor Patrick hace 2 años
padre
commit
b35480f966

+ 0 - 0
cosmwasm/contracts/global-accountant/.cargo/config → cosmwasm/.cargo/config


+ 11 - 53
cosmwasm/contracts/global-accountant/src/contract.rs

@@ -2,15 +2,15 @@ use std::marker::PhantomData;
 
 use accountant::{
     query_balance, query_modification,
-    state::{account, transfer, Kind, Modification, Reason, TokenAddress, Transfer},
+    state::{account, transfer, Kind, Modification, TokenAddress, Transfer},
     validate_transfer,
 };
 use anyhow::{ensure, Context};
 #[cfg(not(feature = "library"))]
 use cosmwasm_std::entry_point;
 use cosmwasm_std::{
-    from_binary, to_binary, Binary, ConversionOverflowError, CosmosMsg, Deps, DepsMut, Empty, Env,
-    Event, MessageInfo, Order, Response, StdError, StdResult, Uint256, WasmMsg,
+    from_binary, to_binary, Binary, ConversionOverflowError, Deps, DepsMut, Empty, Env, Event,
+    MessageInfo, Order, Response, StdError, StdResult, Uint256,
 };
 use cw2::set_contract_version;
 use cw_storage_plus::Bound;
@@ -31,7 +31,7 @@ use crate::{
         AllTransfersResponse, BatchTransferStatusResponse, ChainRegistrationResponse, ExecuteMsg,
         MigrateMsg, MissingObservation, MissingObservationsResponse, Observation, ObservationError,
         ObservationStatus, QueryMsg, SubmitObservationResponse, TransferDetails, TransferStatus,
-        Upgrade, SUBMITTED_OBSERVATIONS_PREFIX,
+        SUBMITTED_OBSERVATIONS_PREFIX,
     },
     state::{Data, PendingTransfer, CHAIN_REGISTRATIONS, DIGESTS, PENDING_TRANSFERS},
 };
@@ -64,7 +64,7 @@ pub fn migrate(_deps: DepsMut<WormholeQuery>, _env: Env, _msg: MigrateMsg) -> St
 #[cfg_attr(not(feature = "library"), entry_point)]
 pub fn execute(
     deps: DepsMut<WormholeQuery>,
-    env: Env,
+    _env: Env,
     info: MessageInfo,
     msg: ExecuteMsg,
 ) -> Result<Response, AnyError> {
@@ -74,16 +74,7 @@ pub fn execute(
             guardian_set_index,
             signature,
         } => submit_observations(deps, info, observations, guardian_set_index, signature),
-        // ExecuteMsg::ModifyBalance {
-        //     modification,
-        //     guardian_set_index,
-        //     signatures,
-        // } => modify_balance(deps, info, modification, guardian_set_index, signatures),
-        ExecuteMsg::UpgradeContract {
-            upgrade,
-            guardian_set_index,
-            signatures,
-        } => upgrade_contract(deps, env, info, upgrade, guardian_set_index, signatures),
+
         ExecuteMsg::SubmitVaas { vaas } => submit_vaas(deps, info, vaas),
     }
 }
@@ -289,41 +280,6 @@ fn modify_balance(
     Ok(event)
 }
 
-fn upgrade_contract(
-    deps: DepsMut<WormholeQuery>,
-    env: Env,
-    info: MessageInfo,
-    upgrade: Binary,
-    guardian_set_index: u32,
-    signatures: Vec<Signature>,
-) -> Result<Response, AnyError> {
-    deps.querier
-        .query::<Empty>(
-            &WormholeQuery::VerifyQuorum {
-                data: upgrade.clone(),
-                guardian_set_index,
-                signatures: signatures.into_iter().map(From::from).collect(),
-            }
-            .into(),
-        )
-        .context(ContractError::VerifyQuorum)?;
-
-    let Upgrade { new_addr } = from_binary(&upgrade).context("failed to parse `Upgrade`")?;
-
-    let mut buf = 0u64.to_ne_bytes();
-    buf.copy_from_slice(&new_addr[24..]);
-    let new_contract = u64::from_be_bytes(buf);
-
-    Ok(Response::new()
-        .add_message(CosmosMsg::Wasm(WasmMsg::Migrate {
-            contract_addr: env.contract.address.to_string(),
-            new_code_id: new_contract,
-            msg: to_binary(&MigrateMsg {})?,
-        }))
-        .add_attribute("action", "contract_upgrade")
-        .add_attribute("owner", info.sender))
-}
-
 fn submit_vaas(
     mut deps: DepsMut<WormholeQuery>,
     info: MessageInfo,
@@ -384,7 +340,8 @@ fn handle_vaa(
         bail!(ContractError::DuplicateMessage);
     }
 
-    let evt = if (body.emitter_chain == Chain::Solana || body.emitter_chain == Chain::Wormchain)
+    // We may also accept governance messages from wormchain in the future
+    let mut evt = if body.emitter_chain == Chain::Solana
         && body.emitter_address == wormhole::GOVERNANCE_EMITTER
     {
         let govpacket = serde_wormhole::from_slice(body.payload)
@@ -400,6 +357,8 @@ fn handle_vaa(
         .save(deps.storage, &digest)
         .context("failed to save message digest")?;
 
+    evt = evt.add_attribute("vaa_digest", hex::encode(digest.as_slice()));
+
     Ok(evt)
 }
 
@@ -445,7 +404,6 @@ fn handle_governance_vaa(
                 ModificationKind::Unknown => bail!("unsupported governance action"),
             };
             let amount = Uint256::from_be_bytes(amount.0);
-            let reason = Reason::new(reason);
             let modification = Modification {
                 sequence,
                 chain_id,
@@ -453,7 +411,7 @@ fn handle_governance_vaa(
                 token_address,
                 kind,
                 amount,
-                reason,
+                reason: reason.to_string(),
             };
             modify_balance(deps, info, modification).map_err(|e| e.into())
         }

+ 0 - 27
cosmwasm/contracts/global-accountant/src/msg.rs

@@ -86,11 +86,6 @@ pub struct ObservationError {
     pub error: String,
 }
 
-#[cw_serde]
-pub struct Upgrade {
-    pub new_addr: [u8; 32],
-}
-
 #[cw_serde]
 pub enum ExecuteMsg {
     /// Submit a series of observations.  Once the contract has received a quorum of signatures
@@ -106,28 +101,6 @@ pub enum ExecuteMsg {
         signature: Signature,
     },
 
-    // /// Modifies the balance of a single account.  Used to manually override the balance.
-    // ModifyBalance {
-    //     // A serialized governance vaa containing a serialized `Modification` message.
-    //     // modification_vaa: Binary,
-
-    //     // The index of the guardian set used to sign this modification.
-    //     // guardian_set_index: u32,
-
-    //     // A quorum of signatures for `modification`.
-    //     // signatures: Vec<Signature>,
-    // },
-    UpgradeContract {
-        // A serialized `Upgrade` message.
-        upgrade: Binary,
-
-        // The index of the guardian set used to sign this request.
-        guardian_set_index: u32,
-
-        // A quorum of signatures for `key`.
-        signatures: Vec<Signature>,
-    },
-
     /// Submit one or more signed VAAs to update the on-chain state.  If processing any of the VAAs
     /// returns an error, the entire transaction is aborted and none of the VAAs are committed.
     SubmitVaas {

+ 1 - 20
cosmwasm/contracts/global-accountant/tests/helpers/mod.rs

@@ -89,7 +89,6 @@ impl Contract {
             Kind::Sub => ModificationKind::Subtract,
         };
         let amount = Amount(amount.to_be_bytes());
-        let reason = reason.0;
         let body = Body {
             timestamp: self.sequence as u32,
             nonce: self.sequence as u32,
@@ -106,7 +105,7 @@ impl Contract {
                     token_address,
                     kind,
                     amount,
-                    reason,
+                    reason: reason.into(),
                 },
             },
         };
@@ -134,24 +133,6 @@ impl Contract {
         })
     }
 
-    pub fn upgrade_contract(
-        &mut self,
-        upgrade: Binary,
-        guardian_set_index: u32,
-        signatures: Vec<Signature>,
-    ) -> anyhow::Result<AppResponse> {
-        self.app.execute_contract(
-            Addr::unchecked(ADMIN),
-            self.addr(),
-            &ExecuteMsg::UpgradeContract {
-                upgrade,
-                guardian_set_index,
-                signatures,
-            },
-            &[],
-        )
-    }
-
     pub fn submit_vaas(&mut self, vaas: Vec<Binary>) -> anyhow::Result<AppResponse> {
         self.app.execute_contract(
             Addr::unchecked(ADMIN),

+ 0 - 60
cosmwasm/contracts/global-accountant/tests/upgrade_contract.rs

@@ -1,60 +0,0 @@
-mod helpers;
-
-use cosmwasm_schema::cw_serde;
-use cosmwasm_std::{
-    to_binary, Binary, Deps, DepsMut, Empty, Env, Event, MessageInfo, Response, StdResult,
-};
-use cw_multi_test::ContractWrapper;
-use global_accountant::msg::Upgrade;
-use helpers::*;
-use wormhole_bindings::WormholeQuery;
-
-pub fn instantiate(
-    _deps: DepsMut,
-    _env: Env,
-    _info: MessageInfo,
-    _msg: Empty,
-) -> StdResult<Response> {
-    Ok(Response::default())
-}
-
-pub fn migrate(_deps: DepsMut<WormholeQuery>, _env: Env, _msg: Empty) -> StdResult<Response> {
-    Ok(Response::default().add_event(Event::new("migrate-success")))
-}
-
-pub fn execute(_deps: DepsMut, _env: Env, _info: MessageInfo, _msg: Empty) -> StdResult<Response> {
-    Ok(Response::default())
-}
-
-#[cw_serde]
-struct NewContract;
-
-pub fn query(_deps: Deps, _env: Env, _msg: Empty) -> StdResult<Binary> {
-    to_binary(&NewContract)
-}
-
-#[test]
-fn upgrade() {
-    let (wh, mut contract) = proper_instantiate();
-
-    let new_code_id = contract.app_mut().store_code(Box::new(
-        ContractWrapper::new_with_empty(execute, instantiate, query).with_migrate_empty(migrate),
-    ));
-
-    let mut new_addr = [0u8; 32];
-    new_addr[24..].copy_from_slice(&new_code_id.to_be_bytes());
-
-    let upgrade = to_binary(&Upgrade { new_addr }).unwrap();
-    let signatures = wh.sign(&upgrade);
-
-    let resp = contract
-        .upgrade_contract(upgrade, wh.guardian_set_index(), signatures)
-        .unwrap();
-    resp.assert_event(&Event::new("wasm-migrate-success"));
-
-    contract
-        .app()
-        .wrap()
-        .query_wasm_smart::<NewContract>(contract.addr(), &Empty {})
-        .unwrap();
-}

+ 8 - 8
cosmwasm/packages/accountant/src/contract.rs

@@ -400,7 +400,7 @@ mod tests {
                 token_address: [i as u8; 32].into(),
                 kind: if i % 2 == 0 { Kind::Add } else { Kind::Sub },
                 amount: Uint256::from(i as u128),
-                reason: [0x20u8; 32].into(),
+                reason: "test".into(),
             };
             out.push(m);
         }
@@ -547,7 +547,7 @@ mod tests {
             token_address: tx.data.token_address,
             kind: Kind::Add,
             amount: wrapped,
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
         modify_balance(deps.as_mut(), m).unwrap();
 
@@ -960,7 +960,7 @@ mod tests {
             token_address: [3u8; 32].into(),
             kind: Kind::Add,
             amount: Uint256::from(4u128),
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
 
         let evt = modify_balance(deps.as_mut(), m.clone()).unwrap();
@@ -997,7 +997,7 @@ mod tests {
             token_address: [3u8; 32].into(),
             kind: Kind::Add,
             amount: Uint256::from(4u128),
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
 
         modify_balance(deps.as_mut(), m.clone()).unwrap();
@@ -1020,7 +1020,7 @@ mod tests {
             token_address: [3u8; 32].into(),
             kind: Kind::Add,
             amount: Uint256::from(4u128),
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
 
         modify_balance(deps.as_mut(), m.clone()).unwrap();
@@ -1044,7 +1044,7 @@ mod tests {
             token_address: [3u8; 32].into(),
             kind: Kind::Add,
             amount: Uint256::from(4u128),
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
 
         for i in 0..ITERATIONS {
@@ -1069,7 +1069,7 @@ mod tests {
             token_address: [3u8; 32].into(),
             kind: Kind::Sub,
             amount: Uint256::from(4u128),
-            reason: [0x20u8; 32].into(),
+            reason: "test".into(),
         };
 
         let e = modify_balance(deps.as_mut(), m)
@@ -1251,7 +1251,7 @@ mod tests {
                 token_address: [i as u8; 32].into(),
                 kind: if i % 2 == 0 { Kind::Add } else { Kind::Sub },
                 amount: Uint256::from(i as u128),
-                reason: [0x20u8; 32].into(),
+                reason: "test".into(),
             };
 
             let key = i as u64;

+ 1 - 64
cosmwasm/packages/accountant/src/state.rs

@@ -32,46 +32,6 @@ impl fmt::Display for Kind {
     }
 }
 
-#[cw_serde]
-#[derive(Copy, Default, Eq, Hash, PartialOrd, Ord)]
-#[repr(transparent)]
-pub struct Reason(
-    #[serde(with = "fixed_bytes_as_string_serde")]
-    #[schemars(with = "String")]
-    pub [u8; 32],
-);
-
-impl Reason {
-    pub const fn new(reason: [u8; 32]) -> Reason {
-        Reason(reason)
-    }
-    // pub fn to_string(&self) -> String {
-    //     unsafe { std::str::from_utf8_unchecked(&self.0).to_string() }
-    // }
-}
-
-impl From<[u8; 32]> for Reason {
-    fn from(reason: [u8; 32]) -> Self {
-        Reason(reason)
-    }
-}
-
-impl TryFrom<&str> for Reason {
-    type Error = &'static str;
-    fn try_from(reason: &str) -> Result<Self, Self::Error> {
-        // default all spaces
-        let mut bz = [b' '; 32];
-        if reason.len() <= 32 {
-            for (i, byte) in reason.as_bytes().iter().enumerate() {
-                bz[i] = *byte;
-            }
-            Ok(Reason(bz))
-        } else {
-            Err("reason cannot be longer than 32 bytes")
-        }
-    }
-}
-
 #[cw_serde]
 #[derive(Eq, PartialOrd, Ord)]
 pub struct Modification {
@@ -89,30 +49,7 @@ pub struct Modification {
     // The amount to be modified.
     pub amount: Uint256,
     // A human-readable reason for the modification.
-    pub reason: Reason,
+    pub reason: String,
 }
 
 pub const MODIFICATIONS: Map<u64, Modification> = Map::new("accountant/modifications");
-
-pub mod fixed_bytes_as_string_serde {
-    use serde::{Deserialize, Serialize};
-    use serde::{Deserializer, Serializer};
-
-    pub fn serialize<S: Serializer>(v: &[u8; 32], s: S) -> Result<S::Ok, S::Error> {
-        let str = String::from_utf8((*v).into())
-            .map_err(|_| serde::ser::Error::custom("invalid utf8"))?;
-        String::serialize(&str, s)
-    }
-
-    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 32], D::Error> {
-        static EXPECTING: &str = "reason string of 32 bytes";
-        let str = String::deserialize(d)?;
-        let bz = str.as_bytes();
-        if bz.len() != 32 {
-            return Err(serde::de::Error::invalid_length(32, &EXPECTING));
-        }
-        let mut bz32 = [0u8; 32];
-        bz32.clone_from_slice(bz);
-        Ok(bz32)
-    }
-}

+ 9 - 2
node/cmd/guardiand/adminserver.go

@@ -20,6 +20,7 @@ import (
 
 	"github.com/certusone/wormhole/node/pkg/watchers/evm/connectors"
 	ethcrypto "github.com/ethereum/go-ethereum/crypto"
+	"github.com/holiman/uint256"
 	"golang.org/x/exp/slices"
 
 	"github.com/certusone/wormhole/node/pkg/db"
@@ -171,8 +172,14 @@ func tokenBridgeModifyBalance(req *nodev1.BridgeModifyBalance, timestamp time.Ti
 		return nil, errors.New("the reason should not be larger than 32 bytes")
 	}
 
-	amount := big.NewInt(0)
-	_, ok := amount.SetString(req.Amount, 10)
+	amount_big := big.NewInt(0)
+	amount_big, ok := amount_big.SetString(req.Amount, 10)
+	if !ok {
+		return nil, errors.New("invalid amount")
+	}
+
+	// uint256 has Bytes32 method for easier serialization
+	amount, ok := uint256.FromBig(amount_big)
 	if !ok {
 		return nil, errors.New("invalid amount")
 	}

+ 1 - 1
node/go.mod

@@ -56,6 +56,7 @@ require (
 	github.com/cosmos/cosmos-sdk v0.45.11
 	github.com/google/uuid v1.3.0
 	github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
+	github.com/holiman/uint256 v1.2.1
 	github.com/test-go/testify v1.1.4
 	github.com/wormhole-foundation/wormchain v0.0.0-00010101000000-000000000000
 	github.com/wormhole-foundation/wormhole/sdk v0.0.0-20220926172624-4b38dc650bb0
@@ -161,7 +162,6 @@ require (
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/hdevalence/ed25519consensus v0.1.0 // indirect
 	github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
-	github.com/holiman/uint256 v1.2.0 // indirect
 	github.com/huin/goupnp v1.0.3 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
 	github.com/ipfs/go-cid v0.2.0 // indirect

+ 2 - 3
node/go.sum

@@ -1013,12 +1013,10 @@ github.com/cosmos/iavl v0.15.0-rc3.0.20201009144442-230e9bdf52cd/go.mod h1:3xOIa
 github.com/cosmos/iavl v0.15.0-rc5/go.mod h1:WqoPL9yPTQ85QBMT45OOUzPxG/U/JcJoN7uMjgxke/I=
 github.com/cosmos/iavl v0.15.3/go.mod h1:OLjQiAQ4fGD2KDZooyJG9yz+p2ao2IAYSbke8mVvSA4=
 github.com/cosmos/iavl v0.17.3/go.mod h1:prJoErZFABYZGDHka1R6Oay4z9PrNeFFiMKHDAMOi4w=
-github.com/cosmos/iavl v0.19.1/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
 github.com/cosmos/iavl v0.19.3/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
 github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok=
 github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw=
 github.com/cosmos/ibc-go v1.2.2/go.mod h1:XmYjsRFOs6Q9Cz+CSsX21icNoH27vQKb3squgnCOCbs=
-github.com/cosmos/ibc-go/v3 v3.3.0/go.mod h1:VUWLHw0C3USmTQZnTdkuXXdUdLbW8zsK3lV1Ieposog=
 github.com/cosmos/ibc-go/v4 v4.0.0-rc2/go.mod h1:4LK+uPycPhebJrJ8ebIqvsMEZ0lVRVNTiEyeI9zfB0U=
 github.com/cosmos/ibc-go/v4 v4.2.0 h1:Fx/kKq/uvawrAxk6ZrQ6sEIgffLRU5Cs/AUnvpPBrHI=
 github.com/cosmos/ibc-go/v4 v4.2.0/go.mod h1:57qWScDtfCx3FOMLYmBIKPbOLE6xiVhrgxHAQmbWYXM=
@@ -1785,8 +1783,9 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo
 github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
 github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
 github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
-github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
 github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
+github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
 github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=

+ 2 - 1
node/pkg/proto/node/v1/node.pb.go

@@ -565,7 +565,8 @@ type BridgeModifyBalance struct {
 	TokenAddress string `protobuf:"bytes,6,opt,name=token_address,json=tokenAddress,proto3" json:"token_address,omitempty"`
 	// The kind of modification to be made.
 	Kind ModificationKind `protobuf:"varint,7,opt,name=kind,proto3,enum=node.v1.ModificationKind" json:"kind,omitempty"`
-	// The amount to be modified.
+	// The amount to be modified.  This should be a decimal formatted string indicating the
+	// "raw" amount, not adjusted by the decimals of the token.
 	Amount string `protobuf:"bytes,8,opt,name=amount,proto3" json:"amount,omitempty"`
 	// A human-readable reason for the modification (max 32 bytes).
 	Reason string `protobuf:"bytes,9,opt,name=reason,proto3" json:"reason,omitempty"`

+ 2 - 1
proto/node/v1/node.proto

@@ -158,7 +158,8 @@ message BridgeModifyBalance {
   string token_address = 6;
   // The kind of modification to be made.
   ModificationKind kind = 7;
-  // The amount to be modified.
+  // The amount to be modified.  This should be a decimal formatted string indicating the
+  // "raw" amount, not adjusted by the decimals of the token.
   string amount = 8;
   // A human-readable reason for the modification (max 32 bytes).
   string reason = 9;

+ 1 - 0
sdk/go.mod

@@ -11,6 +11,7 @@ require (
 	github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
+	github.com/holiman/uint256 v1.2.1 // indirect
 	github.com/kr/text v0.2.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect

+ 2 - 0
sdk/go.sum

@@ -174,6 +174,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
 github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
+github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y=
 github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=

+ 11 - 19
sdk/rust/core/src/token.rs

@@ -267,23 +267,14 @@ pub enum Action {
     // Modify balance for tokenbridge
     #[serde(rename = "3")]
     ModifyBalance {
-        // module:  \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge (32)
-        // chainId: \x03\x0c (2)
-        // action: \x03 (1)
-
-        // \x00\x00\x00\x00\x00\x00\x00$
-        sequence: u64, // 8
-
-        // \x00\x01
-        chain_id: u16, // 10
-        // \x00\x01
-        token_chain: u16, // 12
-        // ||||||||||||||||||||||||||||||||
-        token_address: Address, // 44
-        // \x01
-        kind: ModificationKind, // 45
-        amount: Amount,         // 78
-        reason: [u8; 32],       // 110
+        sequence: u64,
+        chain_id: u16,
+        token_chain: u16,
+        token_address: Address,
+        kind: ModificationKind,
+        amount: Amount,
+        #[serde(with = "crate::arraystring")]
+        reason: BString,
     },
 }
 
@@ -367,7 +358,8 @@ mod governance_packet_impl {
         token_address: Address,
         kind: super::ModificationKind,
         amount: Amount,
-        reason: [u8; 32],
+        #[serde(with = "crate::arraystring")]
+        reason: bstr::BString,
     }
 
     impl Serialize for GovernancePacket {
@@ -380,7 +372,7 @@ mod governance_packet_impl {
 
             // The wire format encodes the action before the chain and then appends the actual
             // action payload.
-            match self.action {
+            match self.action.clone() {
                 Action::RegisterChain {
                     chain,
                     emitter_address,

+ 5 - 8
sdk/vaa/payloads.go

@@ -3,9 +3,9 @@ package vaa
 import (
 	"bytes"
 	"encoding/binary"
-	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/holiman/uint256"
 )
 
 // CoreModule is the identifier of the Core module (which is used for governance messages)
@@ -69,7 +69,7 @@ type (
 		TokenChain    ChainID
 		TokenAddress  Address
 		Kind          uint8
-		Amount        *big.Int
+		Amount        *uint256.Int
 		Reason        string
 	}
 
@@ -143,12 +143,9 @@ func (r BodyTokenBridgeModifyBalance) Serialize() []byte {
 	payload.Write(r.TokenAddress[:])
 	payload.WriteByte(r.Kind)
 
-	amount_bytes := r.Amount.Bytes()
-	// zero pad big endian big-int
-	for i := 0; i < 32-len(amount_bytes); i++ {
-		payload.WriteByte(0)
-	}
-	payload.Write(amount_bytes)
+	amount_bytes := r.Amount.Bytes32()
+	payload.Write(amount_bytes[:])
+
 	reason := make([]byte, 32)
 
 	// truncate or pad "reason"

+ 2 - 0
wormchain/go.sum

@@ -1630,6 +1630,8 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo
 github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
 github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
 github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
+github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
+github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
 github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=

+ 1 - 1
wormchain/testutil/keeper/accountant_contract.go

@@ -26,7 +26,7 @@ var ACCOUNTANT_WASM_B64_GZIP = []byte{}
 //     strip = true
 //
 // 3. Compile: `cargo build --target wasm32-unknown-unknown --release`
-// 4. Generate base64 gzip: `cat target/wasm32-unknown-unknown/release/cw_nameservice.wasm|gzip |base64`
+// 4. Generate base64 gzip: `cat target/wasm32-unknown-unknown/release/global_accountant.wasm|gzip |base64`
 // 5. Copy here.
 var _ACCOUNTANT_WASM_B64_GZIP = `H4sIAKDC6mMAA+w6W5BVRZKVWVXnnHtPNxwU3XZkd869w0cTMYTthHa7GrHLZXWcDT92Z2P+mxZ6
 hEZAm8foxkR3izx8jU9EEEReCiJgo6iooO0bEBUVFRWfgDaIgoqKqLCZVed1uxtoR/2YDW8/zqmq

+ 2 - 2
wormchain/x/wormhole/keeper/msg_server_wasmd_test.go

@@ -6,11 +6,11 @@ import (
 	"encoding/binary"
 	"encoding/hex"
 	"fmt"
-	"math/big"
 	"testing"
 	"time"
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
+	"github.com/holiman/uint256"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/tendermint/crypto/sha3"
@@ -482,7 +482,7 @@ func TestWasmdAccountantContractModify(t *testing.T) {
 		TokenChain:    vaa.ChainIDSolana,
 		TokenAddress:  token_address,
 		Kind:          1, // Add
-		Amount:        big.NewInt(1),
+		Amount:        uint256.NewInt(50),
 		Reason:        "test modify",
 	}
 	ts := time.Date(2012, 12, 12, 12, 12, 12, 12, time.UTC)