Repository: osmosis-labs/osmosis
Pull request #4463 (2023-02-28 22:18:18)

chore: v15 changelog
<!-- < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < ☺
v                               ✰  Thanks for creating a PR! ✰    
v    Before smashing the submit button please review the checkboxes.
v    If a checkbox is n/a - please still include it but + a little note why
v    If your PR doesn't close an issue, that's OK!  Just remove the Closes: #XXX line!
☺ > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  -->

Closes: #XXX

## What is the purpose of the change

Updating changelog for v15


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5cdf4fa34..86088cf33 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,32 +40,34 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## Unreleased
-* Validator-Set Preference
-  * [#2892](https://github.com/osmosis-labs/osmosis/pull/2892) Module Wired up and created MsgSetValidatorSetPreference
-  * [#3620](https://github.com/osmosis-labs/osmosis/pull/3260) Add Msgs for Delegate and Undelegate Tokens
-  * [#3599](https://github.com/osmosis-labs/osmosis/pull/3599) Add RedelegateValidatorSet message
-  * [#3686](https://github.com/osmosis-labs/osmosis/pull/3686) Add WithdrawDelegationRewards message
-  * [#3843](https://github.com/osmosis-labs/osmosis/pull/3843) Cli support and tested SetValSet, DelValSet, UnDelValSet
-  * [#3810](https://github.com/osmosis-labs/osmosis/pull/3810) Allow migration of x/lockup uosmo to staking to a valset preference
-  * [#3966](https://github.com/osmosis-labs/osmosis/pull/3966) Add Redelegate, Withdraw cli commands and sim_msgs
+## v15.0.0
+
+This release containts the following new modules:
+- ProtoRev module (x/protorev). This module captures MEV via in-protocol cyclic arbitrage and distributes the revenue back to the protocol based on governance. Developed by the Skip team.
+- Validator Set Preference module (x/valset-pref). This module gives users the ability to delegate to multiple validators according to their preference list.
+- Pool Manager module (x/poolmanager). This module manages the infrastructure around pool creation and swaps. It serves as a unified entrypoint for any swap related message or query. This module is extracted from the pre-existing `x/gamm`. It is the first milestone on the path towards delivering concentrated liquidity.
+
+### Features
+
   * [#4107](https://github.com/osmosis-labs/osmosis/pull/4107) Add superfluid unbond partial amount
   * [#4207](https://github.com/osmosis-labs/osmosis/pull/4207) Add support for Async Interchain Queries
   * [#4248](https://github.com/osmosis-labs/osmosis/pull/4248) Add panic recovery to `MultihopEstimateInGivenExactAmountOut`, `MultihopEstimateOutGivenExactAmountIn` and `RouteExactAmountOut`
   * [#3911](https://github.com/osmosis-labs/osmosis/pull/3911) Add Packet Forward Middleware
+  * [#4244](https://github.com/osmosis-labs/osmosis/pull/4244) Consensus min gas fee of .0025 uosmo
+  * [#4340](https://github.com/osmosis-labs/osmosis/pull/4340) Added rate limits according to: https://www.mintscan.io/osmosis/proposals/427
+  * [#4207](https://github.com/osmosis-labs/osmosis/pull/4207) Integrate Async ICQ.
 
-## Misc Improvements
+### Misc Improvements
   * [#4131](https://github.com/osmosis-labs/osmosis/pull/4141) Add GatherValuesFromStorePrefixWithKeyParser function to osmoutils.
   * [#4388](https://github.com/osmosis-labs/osmosis/pull/4388) Increase the max allowed contract size for non-proposal contracts to 3MB
   * [#4384](https://github.com/osmosis-labs/osmosis/pull/4384) migrate stXXX/XXX constant product pools 833, 817, 810 to stable swap
 
 ### API breaks
 
-* [#3763](https://github.com/osmosis-labs/osmosis/pull/3763) Remove Osmosis gamm and twap `bindings` that were previously supported as custom wasm plugins.
+* [#3766](https://github.com/osmosis-labs/osmosis/pull/3766) Remove Osmosis gamm and twap `bindings` that were previously supported as custom wasm plugins.
 * [#3905](https://github.com/osmosis-labs/osmosis/pull/3905) Deprecate gamm queries `NumPools`, `EstimateSwapExactAmountIn` and `EstimateSwapExactAmountOut`.
 * [#3907](https://github.com/osmosis-labs/osmosis/pull/3907) Add `NumPools`, `EstimateSwapExactAmountIn` and `EstimateSwapExactAmountOut` query in poolmanager module to stargate whitelist.
 * [#3880](https://github.com/osmosis-labs/osmosis/pull/3880) Switch usage of proto-generated SwapAmountInRoute and SwapAmountOutRoute in x/gamm to import the structs from x/poolmanager module.
-* [#4250](https://github.com/osmosis-labs/osmosis/pull/4250) Add denom metadata for uosmo, uion
 
 ### Bug Fix
 
@@ -73,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * [#3746](https://github.com/osmosis-labs/osmosis/pull/3746) Make ApplyFuncIfNoErr logic preserve panics for OutOfGas behavior.
 * [#4306](https://github.com/osmosis-labs/osmosis/pull/4306) Prevent adding more tokens to an already finished gauge
 * [#4359](https://github.com/osmosis-labs/osmosis/pull/4359) Fix incorrect time delta due to nanoseconds in time causing twap jitter.
+* [#4250](https://github.com/osmosis-labs/osmosis/pull/4250) Add denom metadata for uosmo, uion
 
 
 ## v14.0.1
diff --git a/go.mod b/go.mod
index 7989fea29..b4bd78a6e 100644
--- a/go.mod
+++ b/go.mod
@@ -312,8 +312,8 @@ replace (
 	github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.30.0-osmo-v15
 	// dragonberry
 	github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
-	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/0907b756eecb4902814b88c268083e91b1b7c8a7
-	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb
+	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
+	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
 	// use cosmos-compatible protobufs
 	github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
 	// Informal Tendermint fork
diff --git a/go.sum b/go.sum
index f267b4a1d..313b7ff64 100644
--- a/go.sum
+++ b/go.sum
@@ -855,8 +855,8 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
 github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
 github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
 github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
-github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb h1:K//IQPAZlBDgnso7XDM3WTS9Ce0U7npkGNG4a9o9OPQ=
-github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb/go.mod h1:rud0OaBIuq3+qOqtwT4SR7Q7iSzRp7w41fjninTjfnQ=
+github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310 h1:3CTaTTiiFg/JoNLP2jGMjooQaeXSzQus/rZMllAlFy4=
+github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310/go.mod h1:rud0OaBIuq3+qOqtwT4SR7Q7iSzRp7w41fjninTjfnQ=
 github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY=
 github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
 github.com/osmosis-labs/osmosis/osmomath v0.0.0-20230105183030-bccf5202f260 h1:+EbINXzHQyDtHje2CND357A22H2zUpceTtwJClC9IAM=
diff --git a/osmomath/go.mod b/osmomath/go.mod
index e44a16cd7..90c32a4d9 100644
--- a/osmomath/go.mod
+++ b/osmomath/go.mod
@@ -4,7 +4,7 @@ go 1.19
 
 require (
 	github.com/cosmos/cosmos-sdk v0.46.10
-	github.com/stretchr/testify v1.8.1
+	github.com/stretchr/testify v1.8.2
 	gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -90,8 +90,8 @@ require (
 )
 
 replace (
-	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/0907b756eecb4902814b88c268083e91b1b7c8a7
-	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb
+	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
+	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
 	// use cosmos-compatible protobufs
 	github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
 	// use grpc compatible with cosmos protobufs
diff --git a/osmomath/go.sum b/osmomath/go.sum
index 9a1f626c3..45d59210f 100644
--- a/osmomath/go.sum
+++ b/osmomath/go.sum
@@ -300,7 +300,7 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
-github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb h1:K//IQPAZlBDgnso7XDM3WTS9Ce0U7npkGNG4a9o9OPQ=
+github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310 h1:3CTaTTiiFg/JoNLP2jGMjooQaeXSzQus/rZMllAlFy4=
 github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -388,8 +388,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
 github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
diff --git a/osmoutils/go.mod b/osmoutils/go.mod
index 3c7321a33..5e44a0197 100644
--- a/osmoutils/go.mod
+++ b/osmoutils/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/gogo/protobuf v1.3.3
 	github.com/spf13/cobra v1.6.1
 	github.com/spf13/pflag v1.0.5
-	github.com/stretchr/testify v1.8.1
+	github.com/stretchr/testify v1.8.2
 	github.com/tendermint/tendermint v0.34.24
 	github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b
 	golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
@@ -132,8 +132,8 @@ require (
 )
 
 replace (
-	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/0907b756eecb4902814b88c268083e91b1b7c8a7
-	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb
+	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
+	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
 	// use cosmos-compatible protobufs
 	github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
 	// use grpc compatible with cosmos protobufs
diff --git a/osmoutils/go.sum b/osmoutils/go.sum
index 4d7fa566e..2f47e4769 100644
--- a/osmoutils/go.sum
+++ b/osmoutils/go.sum
@@ -596,7 +596,7 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
 github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
-github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb h1:K//IQPAZlBDgnso7XDM3WTS9Ce0U7npkGNG4a9o9OPQ=
+github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310 h1:3CTaTTiiFg/JoNLP2jGMjooQaeXSzQus/rZMllAlFy4=
 github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -745,8 +745,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
 github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
diff --git a/proto/osmosis/protorev/v1beta1/genesis.proto b/proto/osmosis/protorev/v1beta1/genesis.proto
index a9dacdae2..9e9873dfa 100644
--- a/proto/osmosis/protorev/v1beta1/genesis.proto
+++ b/proto/osmosis/protorev/v1beta1/genesis.proto
@@ -4,11 +4,58 @@ package osmosis.protorev.v1beta1;
 import "gogoproto/gogo.proto";
 import "osmosis/protorev/v1beta1/protorev.proto";
 import "osmosis/protorev/v1beta1/params.proto";
+import "cosmos_proto/cosmos.proto";
+
+import "cosmos/base/v1beta1/coin.proto";
 
 option go_package = "github.com/osmosis-labs/osmosis/v15/x/protorev/types";
 
 // GenesisState defines the protorev module's genesis state.
 message GenesisState {
-  // Module Parameters
+  // Parameters for the protorev module.
   Params params = 1 [ (gogoproto.nullable) = false ];
+  // Token pair arb routes for the protorev module (hot routes).
+  repeated TokenPairArbRoutes token_pair_arb_routes = 2 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"token_pair_arb_routes\""
+  ];
+  // The base denominations being used to create cyclic arbitrage routes via the
+  // highest liquidity method.
+  repeated BaseDenom base_denoms = 3 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"base_denoms\""
+  ];
+  // The pool weights that are being used to calculate the weight (compute cost)
+  // of each route.
+  PoolWeights pool_weights = 4 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"pool_weights\""
+  ];
+  // The number of days since module genesis.
+  uint64 days_since_module_genesis = 5
+      [ (gogoproto.moretags) = "yaml:\"days_since_module_genesis\"" ];
+  // The fees the developer account has accumulated over time.
+  repeated cosmos.base.v1beta1.Coin developer_fees = 6 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"developer_fees\""
+  ];
+  // The latest block height that the module has processed.
+  uint64 latest_block_height = 7
+      [ (gogoproto.moretags) = "yaml:\"latest_block_height\"" ];
+  // The developer account address of the module.
+  string developer_address = 8 [
+    (cosmos_proto.scalar) = "cosmos.Address",
+    (gogoproto.moretags) = "yaml:\"developer_address\""
+  ];
+  // Max pool points per block i.e. the maximum compute time (in ms)
+  // that protorev can use per block.
+  uint64 max_pool_points_per_block = 9
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_block\"" ];
+  // Max pool points per tx i.e. the maximum compute time (in ms) that
+  // protorev can use per tx.
+  uint64 max_pool_points_per_tx = 10
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_tx\"" ];
+  // The number of pool points that have been consumed in the current block.
+  uint64 point_count_for_block = 11
+      [ (gogoproto.moretags) = "yaml:\"point_count_for_block\"" ];
 }
\ No newline at end of file
diff --git a/proto/osmosis/protorev/v1beta1/params.proto b/proto/osmosis/protorev/v1beta1/params.proto
index f3a7ca7a2..499499b94 100644
--- a/proto/osmosis/protorev/v1beta1/params.proto
+++ b/proto/osmosis/protorev/v1beta1/params.proto
@@ -2,11 +2,17 @@ syntax = "proto3";
 package osmosis.protorev.v1beta1;
 
 import "gogoproto/gogo.proto";
+import "cosmos_proto/cosmos.proto";
 
 option go_package = "github.com/osmosis-labs/osmosis/v15/x/protorev/types";
 
 // Params defines the parameters for the module.
 message Params {
-  // Boolean whether the module is going to be enabled
-  bool enabled = 1;
+  // Boolean whether the protorev module is enabled.
+  bool enabled = 1 [ (gogoproto.moretags) = "yaml:\"enabled\"" ];
+  // The admin account (settings manager) of the protorev module.
+  string admin = 2 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
 }
\ No newline at end of file
diff --git a/proto/osmosis/protorev/v1beta1/protorev.proto b/proto/osmosis/protorev/v1beta1/protorev.proto
index d877d6840..de64064f6 100644
--- a/proto/osmosis/protorev/v1beta1/protorev.proto
+++ b/proto/osmosis/protorev/v1beta1/protorev.proto
@@ -13,11 +13,14 @@ message TokenPairArbRoutes {
   option (gogoproto.equal) = true;
 
   // Stores all of the possible hot paths for a given pair of tokens
-  repeated Route arb_routes = 1;
+  repeated Route arb_routes = 1 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"arb_routes\""
+  ];
   // Token denomination of the first asset
-  string token_in = 2;
+  string token_in = 2 [ (gogoproto.moretags) = "yaml:\"token_in\"" ];
   // Token denomination of the second asset
-  string token_out = 3;
+  string token_out = 3 [ (gogoproto.moretags) = "yaml:\"token_out\"" ];
 }
 
 // Route is a hot route for a given pair of tokens
@@ -26,12 +29,16 @@ message Route {
 
   // The pool IDs that are travered in the directed cyclic graph (traversed left
   // -> right)
-  repeated Trade trades = 1;
+  repeated Trade trades = 1 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"trades\""
+  ];
   // The step size that will be used to find the optimal swap amount in the
   // binary search
   string step_size = 2 [
     (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
-    (gogoproto.nullable) = true
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"step_size\""
   ];
 }
 
@@ -39,28 +46,31 @@ message Route {
 message Trade {
   option (gogoproto.equal) = true;
 
-  // The pool IDs that are travered in the directed cyclic graph (traversed left
-  // -> right)
-  uint64 pool = 1;
-  // The denom of token A that is traded
-  string token_in = 2;
-  // The denom of token B that is traded
-  string token_out = 3;
+  // The pool id of the pool that is traded on
+  uint64 pool = 1 [ (gogoproto.moretags) = "yaml:\"pool\"" ];
+  // The denom of the token that is traded
+  string token_in = 2 [ (gogoproto.moretags) = "yaml:\"token_in\"" ];
+  // The denom of the token that is received
+  string token_out = 3 [ (gogoproto.moretags) = "yaml:\"token_out\"" ];
 }
 
 // RouteStatistics contains the number of trades the module has executed after a
 // swap on a given route and the profits from the trades
 message RouteStatistics {
   // profits is the total profit from all trades on this route
-  repeated cosmos.base.v1beta1.Coin profits = 1;
+  repeated cosmos.base.v1beta1.Coin profits = 1 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"profits\""
+  ];
   // number_of_trades is the number of trades the module has executed using this
   // route
   string number_of_trades = 2 [
     (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
-    (gogoproto.nullable) = false
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"number_of_trades\""
   ];
   // route is the route that was used (pool ids along the arbitrage route)
-  repeated uint64 route = 3;
+  repeated uint64 route = 3 [ (gogoproto.moretags) = "yaml:\"route\"" ];
 }
 
 // PoolWeights contains the weights of all of the different pool types. This
@@ -70,11 +80,13 @@ message RouteStatistics {
 // pool type.
 message PoolWeights {
   // The weight of a stableswap pool
-  uint64 stable_weight = 1;
+  uint64 stable_weight = 1 [ (gogoproto.moretags) = "yaml:\"stable_weight\"" ];
   // The weight of a balancer pool
-  uint64 balancer_weight = 2;
+  uint64 balancer_weight = 2
+      [ (gogoproto.moretags) = "yaml:\"balancer_weight\"" ];
   // The weight of a concentrated pool
-  uint64 concentrated_weight = 3;
+  uint64 concentrated_weight = 3
+      [ (gogoproto.moretags) = "yaml:\"concentrated_weight\"" ];
 }
 
 // BaseDenom represents a single base denom that the module uses for its
@@ -82,11 +94,12 @@ message PoolWeights {
 // binary search that is used to find the optimal swap amount
 message BaseDenom {
   // The denom i.e. name of the base denom (ex. uosmo)
-  string denom = 1;
+  string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
   // The step size of the binary search that is used to find the optimal swap
   // amount
   string step_size = 2 [
     (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
-    (gogoproto.nullable) = false
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"step_size\""
   ];
 }
\ No newline at end of file
diff --git a/proto/osmosis/protorev/v1beta1/query.proto b/proto/osmosis/protorev/v1beta1/query.proto
index 6e959d7a6..6c95dcfae 100644
--- a/proto/osmosis/protorev/v1beta1/query.proto
+++ b/proto/osmosis/protorev/v1beta1/query.proto
@@ -116,7 +116,10 @@ message QueryParamsRequest {}
 // QueryParamsResponse is response type for the Query/Params RPC method.
 message QueryParamsResponse {
   // params holds all the parameters of this module.
-  Params params = 1 [ (gogoproto.nullable) = false ];
+  Params params = 1 [
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"params\""
+  ];
 }
 
 // QueryGetProtoRevNumberOfTradesRequest is request type for the
@@ -129,7 +132,8 @@ message QueryGetProtoRevNumberOfTradesResponse {
   // number_of_trades is the number of trades the module has executed
   string number_of_trades = 1 [
     (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
-    (gogoproto.nullable) = false
+    (gogoproto.nullable) = false,
+    (gogoproto.moretags) = "yaml:\"number_of_trades\""
   ];
 }
 
@@ -137,14 +141,15 @@ message QueryGetProtoRevNumberOfTradesResponse {
 // Query/GetProtoRevProfitsByDenom RPC method.
 message QueryGetProtoRevProfitsByDenomRequest {
   // denom is the denom to query profits by
-  string denom = 1;
+  string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
 }
 
 // QueryGetProtoRevProfitsByDenomResponse is response type for the
 // Query/GetProtoRevProfitsByDenom RPC method.
 message QueryGetProtoRevProfitsByDenomResponse {
   // profit is the profits of the module by the selected denom
-  cosmos.base.v1beta1.Coin profit = 1;
+  cosmos.base.v1beta1.Coin profit = 1
+      [ (gogoproto.moretags) = "yaml:\"profit\"" ];
 }
 
 // QueryGetProtoRevAllProfitsRequest is request type for the
@@ -155,14 +160,17 @@ message QueryGetProtoRevAllProfitsRequest {}
 // Query/GetProtoRevAllProfits RPC method.
 message QueryGetProtoRevAllProfitsResponse {
   // profits is a list of all of the profits from the module
-  repeated cosmos.base.v1beta1.Coin profits = 1;
+  repeated cosmos.base.v1beta1.Coin profits = 1 [
+    (gogoproto.moretags) = "yaml:\"profits\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // QueryGetProtoRevStatisticsByPoolRequest is request type for the
 // Query/GetProtoRevStatisticsByRoute RPC method.
 message QueryGetProtoRevStatisticsByRouteRequest {
   // route is the set of pool ids to query statistics by i.e. 1,2,3
-  repeated uint64 route = 1;
+  repeated uint64 route = 1 [ (gogoproto.moretags) = "yaml:\"route\"" ];
 }
 
 // QueryGetProtoRevStatisticsByRouteResponse is response type for the
@@ -170,7 +178,10 @@ message QueryGetProtoRevStatisticsByRouteRequest {
 message QueryGetProtoRevStatisticsByRouteResponse {
   // statistics contains the number of trades the module has executed after a
   // swap on a given pool and the profits from the trades
-  RouteStatistics statistics = 1;
+  RouteStatistics statistics = 1 [
+    (gogoproto.moretags) = "yaml:\"statistics\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // QueryGetProtoRevAllRouteStatisticsRequest is request type for the
@@ -182,7 +193,10 @@ message QueryGetProtoRevAllRouteStatisticsRequest {}
 message QueryGetProtoRevAllRouteStatisticsResponse {
   // statistics contains the number of trades/profits the module has executed on
   // all routes it has successfully executed a trade on
-  repeated RouteStatistics statistics = 1 [ (gogoproto.nullable) = false ];
+  repeated RouteStatistics statistics = 1 [
+    (gogoproto.moretags) = "yaml:\"statistics\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // QueryGetProtoRevTokenPairArbRoutesRequest is request type for the
@@ -194,7 +208,10 @@ message QueryGetProtoRevTokenPairArbRoutesRequest {}
 message QueryGetProtoRevTokenPairArbRoutesResponse {
   // routes is a list of all of the hot routes that the module is currently
   // arbitraging
-  repeated TokenPairArbRoutes routes = 1;
+  repeated TokenPairArbRoutes routes = 1 [
+    (gogoproto.moretags) = "yaml:\"routes\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // QueryGetProtoRevAdminAccountRequest is request type for the
@@ -205,7 +222,7 @@ message QueryGetProtoRevAdminAccountRequest {}
 // Query/GetProtoRevAdminAccount RPC method.
 message QueryGetProtoRevAdminAccountResponse {
   // admin_account is the admin account of the module
-  string admin_account = 1;
+  string admin_account = 1 [ (gogoproto.moretags) = "yaml:\"admin_account\"" ];
 }
 
 // QueryGetProtoRevDeveloperAccountRequest is request type for the
@@ -216,7 +233,8 @@ message QueryGetProtoRevDeveloperAccountRequest {}
 // Query/GetProtoRevDeveloperAccount RPC method.
 message QueryGetProtoRevDeveloperAccountResponse {
   // developer_account is the developer account of the module
-  string developer_account = 1;
+  string developer_account = 1
+      [ (gogoproto.moretags) = "yaml:\"developer_account\"" ];
 }
 
 // QueryGetProtoRevPoolWeightsRequest is request type for the
@@ -227,7 +245,8 @@ message QueryGetProtoRevPoolWeightsRequest {}
 // Query/GetProtoRevPoolWeights RPC method.
 message QueryGetProtoRevPoolWeightsResponse {
   // pool_weights is a list of all of the pool weights
-  PoolWeights pool_weights = 1;
+  PoolWeights pool_weights = 1
+      [ (gogoproto.moretags) = "yaml:\"pool_weights\"", (gogoproto.nullable) = false ];
 }
 
 // QueryGetProtoRevMaxPoolPointsPerBlockRequest is request type for the
@@ -239,7 +258,8 @@ message QueryGetProtoRevMaxPoolPointsPerBlockRequest {}
 message QueryGetProtoRevMaxPoolPointsPerBlockResponse {
   // max_pool_points_per_block is the maximum number of pool points that can be
   // consumed per block
-  uint64 max_pool_points_per_block = 1;
+  uint64 max_pool_points_per_block = 1
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_block\"" ];
 }
 
 // QueryGetProtoRevMaxPoolPointsPerTxRequest is request type for the
@@ -251,7 +271,8 @@ message QueryGetProtoRevMaxPoolPointsPerTxRequest {}
 message QueryGetProtoRevMaxPoolPointsPerTxResponse {
   // max_pool_points_per_tx is the maximum number of pool points that can be
   // consumed per transaction
-  uint64 max_pool_points_per_tx = 1;
+  uint64 max_pool_points_per_tx = 1
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_tx\"" ];
 }
 
 // QueryGetProtoRevBaseDenomsRequest is request type for the
@@ -262,7 +283,10 @@ message QueryGetProtoRevBaseDenomsRequest {}
 // Query/GetProtoRevBaseDenoms RPC method.
 message QueryGetProtoRevBaseDenomsResponse {
   // base_denoms is a list of all of the base denoms and step sizes
-  repeated BaseDenom base_denoms = 1;
+  repeated BaseDenom base_denoms = 1 [
+    (gogoproto.moretags) = "yaml:\"base_denoms\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // QueryGetProtoRevEnabledRequest is request type for the
@@ -273,5 +297,5 @@ message QueryGetProtoRevEnabledRequest {}
 // Query/GetProtoRevEnabled RPC method.
 message QueryGetProtoRevEnabledResponse {
   // enabled is whether the module is enabled
-  bool enabled = 1;
+  bool enabled = 1 [ (gogoproto.moretags) = "yaml:\"enabled\"" ];
 }
\ No newline at end of file
diff --git a/proto/osmosis/protorev/v1beta1/tx.proto b/proto/osmosis/protorev/v1beta1/tx.proto
index afb855f13..01c94a780 100644
--- a/proto/osmosis/protorev/v1beta1/tx.proto
+++ b/proto/osmosis/protorev/v1beta1/tx.proto
@@ -4,6 +4,7 @@ package osmosis.protorev.v1beta1;
 import "gogoproto/gogo.proto";
 import "google/api/annotations.proto";
 import "osmosis/protorev/v1beta1/protorev.proto";
+import "cosmos_proto/cosmos.proto";
 
 option go_package = "github.com/osmosis-labs/osmosis/v15/x/protorev/types";
 
@@ -54,9 +55,15 @@ service Msg {
 // MsgSetHotRoutes defines the Msg/SetHotRoutes request type.
 message MsgSetHotRoutes {
   // admin is the account that is authorized to set the hot routes.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // hot_routes is the list of hot routes to set.
-  repeated TokenPairArbRoutes hot_routes = 2;
+  repeated TokenPairArbRoutes hot_routes = 2 [
+    (gogoproto.moretags) = "yaml:\"hot_routes\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // MsgSetHotRoutesResponse defines the Msg/SetHotRoutes response type.
@@ -65,10 +72,14 @@ message MsgSetHotRoutesResponse {}
 // MsgSetDeveloperAccount defines the Msg/SetDeveloperAccount request type.
 message MsgSetDeveloperAccount {
   // admin is the account that is authorized to set the developer account.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // developer_account is the account that will receive a portion of the profits
   // from the protorev module.
-  string developer_account = 2;
+  string developer_account = 2
+      [ (gogoproto.moretags) = "yaml:\"developer_account\"" ];
 }
 
 // MsgSetDeveloperAccountResponse defines the Msg/SetDeveloperAccount response
@@ -78,9 +89,15 @@ message MsgSetDeveloperAccountResponse {}
 // MsgSetPoolWeights defines the Msg/SetPoolWeights request type.
 message MsgSetPoolWeights {
   // admin is the account that is authorized to set the pool weights.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // pool_weights is the list of pool weights to set.
-  PoolWeights pool_weights = 2;
+  PoolWeights pool_weights = 2 [
+    (gogoproto.moretags) = "yaml:\"pool_weights\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // MsgSetPoolWeightsResponse defines the Msg/SetPoolWeights response type.
@@ -89,10 +106,14 @@ message MsgSetPoolWeightsResponse {}
 // MsgSetMaxPoolPointsPerTx defines the Msg/SetMaxPoolPointsPerTx request type.
 message MsgSetMaxPoolPointsPerTx {
   // admin is the account that is authorized to set the max pool points per tx.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // max_pool_points_per_tx is the maximum number of pool points that can be
   // consumed per transaction.
-  uint64 max_pool_points_per_tx = 2;
+  uint64 max_pool_points_per_tx = 2
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_tx\"" ];
 }
 
 // MsgSetMaxPoolPointsPerTxResponse defines the Msg/SetMaxPoolPointsPerTx
@@ -104,10 +125,14 @@ message MsgSetMaxPoolPointsPerTxResponse {}
 message MsgSetMaxPoolPointsPerBlock {
   // admin is the account that is authorized to set the max pool points per
   // block.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // max_pool_points_per_block is the maximum number of pool points that can be
   // consumed per block.
-  uint64 max_pool_points_per_block = 2;
+  uint64 max_pool_points_per_block = 2
+      [ (gogoproto.moretags) = "yaml:\"max_pool_points_per_block\"" ];
 }
 
 // MsgSetMaxPoolPointsPerBlockResponse defines the
@@ -117,9 +142,15 @@ message MsgSetMaxPoolPointsPerBlockResponse {}
 // MsgSetBaseDenoms defines the Msg/SetBaseDenoms request type.
 message MsgSetBaseDenoms {
   // admin is the account that is authorized to set the base denoms.
-  string admin = 1;
+  string admin = 1 [
+    (gogoproto.moretags) = "yaml:\"admin\"",
+    (cosmos_proto.scalar) = "cosmos.AddressString"
+  ];
   // base_denoms is the list of base denoms to set.
-  repeated BaseDenom base_denoms = 2;
+  repeated BaseDenom base_denoms = 2 [
+    (gogoproto.moretags) = "yaml:\"base_denoms\"",
+    (gogoproto.nullable) = false
+  ];
 }
 
 // MsgSetBaseDenomsResponse defines the Msg/SetBaseDenoms response type.
diff --git a/x/gamm/README.md b/x/gamm/README.md
index e5c1c38ae..f2c65a6a8 100644
--- a/x/gamm/README.md
+++ b/x/gamm/README.md
@@ -36,7 +36,7 @@ us safe when it comes to the malicious creation of unneeded pools.
 
 #### Joining Pool
 
-When joining a pool without swapping - with `JoinPool`, a user can provide the maximum amount of tokens `TokenInMaxs'
+When joining a pool without swapping - with `JoinPool`, a user can provide the maximum amount of tokens `TokenInMaxs`
 they're willing to deposit. This argument must contain all the denominations from the pool or no tokens at all, 
 otherwise, the tx will be aborted.
 If `TokenInMaxs` contains no tokens, the calculations are done based on the user's balance as the only constraint.
diff --git a/x/ibc-hooks/go.mod b/x/ibc-hooks/go.mod
index dfc5e836a..7911eda2b 100644
--- a/x/ibc-hooks/go.mod
+++ b/x/ibc-hooks/go.mod
@@ -110,7 +110,7 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/spf13/viper v1.15.0 // indirect
-	github.com/stretchr/testify v1.8.1 // indirect
+	github.com/stretchr/testify v1.8.2 // indirect
 	github.com/subosito/gotenv v1.4.2 // indirect
 	github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
 	github.com/tendermint/btcd v0.1.1 // indirect
@@ -143,8 +143,8 @@ replace (
 	github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.30.0-osmo-v15
 	// dragonberry
 	github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0
-	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/0907b756eecb4902814b88c268083e91b1b7c8a7
-	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb
+	// Our cosmos-sdk branch is:  https://github.com/osmosis-labs/cosmos-sdk, current branch: v15.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/44b40d47f3108c29f07fd115e5a92b387fb7a6bd
+	github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310
 	// use cosmos-compatible protobufs
 	github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
 )
diff --git a/x/ibc-hooks/go.sum b/x/ibc-hooks/go.sum
index 4998ca6b4..dcf865075 100644
--- a/x/ibc-hooks/go.sum
+++ b/x/ibc-hooks/go.sum
@@ -625,11 +625,10 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
 github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
 github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
-github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230220032354-0907b756eecb h1:K//IQPAZlBDgnso7XDM3WTS9Ce0U7npkGNG4a9o9OPQ=
+github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230228211301-44b40d47f310 h1:3CTaTTiiFg/JoNLP2jGMjooQaeXSzQus/rZMllAlFy4=
 github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230105184425-1e6fcd979d99 h1:8yYGNa5u8MmFdh+FpZQ7/4jlGABd5XSDfPcENJE9HXs=
 github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230105184425-1e6fcd979d99/go.mod h1:K4de+n3DtLdueen98dOzaRXZvqMd8JvigL8O1xW445o=
-github.com/osmosis-labs/wasmd v0.29.2-0.20221222131554-7c8ea36a6e30 h1:6uMi7HhPSwvKKU7j5NqljseFTEz4I7qHr+IPnnn42Ck=
-github.com/osmosis-labs/wasmd v0.29.2-0.20221222131554-7c8ea36a6e30/go.mod h1:5fDYJyMXBq6u2iuHqqOTYiZ5NitIOeIW5k7qEXqbwJE=
+github.com/osmosis-labs/wasmd v0.30.0-osmo-v15 h1:vjbzq9ta/KmQwUM6PcRmrBJuDwILgLbV4POypC1Uhn8=
 github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -781,8 +780,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
 github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
diff --git a/x/protorev/genesis.go b/x/protorev/genesis.go
deleted file mode 100644
index 9d6943c19..000000000
--- a/x/protorev/genesis.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package protorev
-
-import (
-	sdk "github.com/cosmos/cosmos-sdk/types"
-
-	"github.com/osmosis-labs/osmosis/v15/x/protorev/keeper"
-	"github.com/osmosis-labs/osmosis/v15/x/protorev/types"
-)
-
-// InitGenesis initializes the module's state from a provided genesis state.
-func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) {
-	// Perform stateless validation on the genesis state
-	if err := genState.Validate(); err != nil {
-		panic(err)
-	}
-
-	// Init module state
-	k.SetParams(ctx, genState.Params)
-	k.SetProtoRevEnabled(ctx, genState.Params.Enabled)
-	k.SetDaysSinceModuleGenesis(ctx, 0)
-	k.SetLatestBlockHeight(ctx, uint64(ctx.BlockHeight()))
-	k.SetPointCountForBlock(ctx, 0)
-
-	// Configure max pool points per block. This roughly correlates to the ms of execution time protorev will
-	// take per block
-	if err := k.SetMaxPointsPerBlock(ctx, 100); err != nil {
-		panic(err)
-	}
-
-	// Configure max pool points per tx. This roughly correlates to the ms of execution time protorev will take
-	// per tx
-	if err := k.SetMaxPointsPerTx(ctx, 18); err != nil {
-		panic(err)
-	}
-
-	// Configure the pool weights for genesis. This roughly correlates to the ms of execution time
-	// by pool type
-	poolWeights := types.PoolWeights{
-		StableWeight:       5, // it takes around 5 ms to simulate and execute a stable swap
-		BalancerWeight:     2, // it takes around 2 ms to simulate and execute a balancer swap
-		ConcentratedWeight: 2, // it takes around 2 ms to simulate and execute a concentrated swap
-	}
-	k.SetPoolWeights(ctx, poolWeights)
-
-	// Configure the initial base denoms used for cyclic route building. The order of the list of base
-	// denoms is the order in which routes will be prioritized i.e. routes will be built and simulated in a
-	// first come first serve basis that is based on the order of the base denoms.
-	baseDenoms := []*types.BaseDenom{
-		{
-			Denom:    types.OsmosisDenomination,
-			StepSize: sdk.NewInt(1_000_000),
-		},
-	}
-	if err := k.SetBaseDenoms(ctx, baseDenoms); err != nil {
-		panic(err)
-	}
-
-	// Currently configured to be the Skip dev team's address
-	// See https://github.com/osmosis-labs/osmosis/issues/4349 for more details
-	// Note that governance has full ability to change this live on-chain, and this admin can at most prevent protorev from working.
-	// All the settings manager's controls have limits, so it can't lead to a chain halt, excess processing time or prevention of swaps.
-	adminAccount, err := sdk.AccAddressFromBech32("osmo17nv67dvc7f8yr00rhgxd688gcn9t9wvhn783z4")
-	if err != nil {
-		panic(err)
-	}
-	k.SetAdminAccount(ctx, adminAccount)
-
-	// Update the pools on genesis
-	if err := k.UpdatePools(ctx); err != nil {
-		panic(err)
-	}
-}
-
-// ExportGenesis returns the module's exported genesis
-func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
-	genesis := types.DefaultGenesis()
-	genesis.Params = k.GetParams(ctx)
-
-	return genesis
-}
diff --git a/x/protorev/keeper/epoch_hook.go b/x/protorev/keeper/epoch_hook.go
index 50a8ca130..46824e36d 100644
--- a/x/protorev/keeper/epoch_hook.go
+++ b/x/protorev/keeper/epoch_hook.go
@@ -31,7 +31,7 @@ func (h EpochHooks) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, ep
 
 // AfterEpochEnd is the epoch end hook.
 func (h EpochHooks) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) error {
-	if enabled, err := h.k.GetProtoRevEnabled(ctx); err == nil && enabled {
+	if h.k.GetProtoRevEnabled(ctx) {
 		switch epochIdentifier {
 		case "week":
 			// Distribute developer fees to the developer account. We do not error check because the developer account
diff --git a/x/protorev/keeper/genesis.go b/x/protorev/keeper/genesis.go
new file mode 100644
index 000000000..83ca0df27
--- /dev/null
+++ b/x/protorev/keeper/genesis.go
@@ -0,0 +1,150 @@
+package keeper
+
+import (
+	sdk "github.com/cosmos/cosmos-sdk/types"
+
+	"github.com/osmosis-labs/osmosis/v15/x/protorev/types"
+)
+
+// InitGenesis initializes the module's state from a provided genesis state.
+func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
+	// Perform stateless validation on the genesis state.
+	if err := genState.Validate(); err != nil {
+		panic(err)
+	}
+
+	// -------------- Init the module state -------------- //
+	// Set the module parameters in state.
+	k.SetParams(ctx, genState.Params)
+
+	// ------------- Route building set up -------------- //
+	// Set all of the token pair arb routes in state.
+	for _, tokenPairArbRoutes := range genState.TokenPairArbRoutes {
+		if err := k.SetTokenPairArbRoutes(ctx, tokenPairArbRoutes.TokenIn, tokenPairArbRoutes.TokenOut, tokenPairArbRoutes); err != nil {
+			panic(err)
+		}
+	}
+
+	// Configure the initial base denoms used for cyclic route building. The order of the list of base
+	// denoms is the order in which routes will be prioritized i.e. routes will be built and simulated in a
+	// first come first serve basis that is based on the order of the base denoms.
+	if err := k.SetBaseDenoms(ctx, genState.BaseDenoms); err != nil {
+		panic(err)
+	}
+
+	// Update the pools on genesis.
+	if err := k.UpdatePools(ctx); err != nil {
+		panic(err)
+	}
+
+	// --------------- Developer set up ----------------- //
+	// Set the developer address if it exists.
+	if genState.DeveloperAddress != "" {
+		account, err := sdk.AccAddressFromBech32(genState.DeveloperAddress)
+		if err != nil {
+			panic(err)
+		}
+
+		k.SetDeveloperAccount(ctx, account)
+	}
+
+	// Set the developer fees that have been collected.
+	for _, fee := range genState.DeveloperFees {
+		if err := k.SetDeveloperFees(ctx, fee); err != nil {
+			panic(err)
+		}
+	}
+
+	// Set the number of days since the module genesis.
+	k.SetDaysSinceModuleGenesis(ctx, genState.DaysSinceModuleGenesis)
+
+	// -------------- Route compute set up -------------- //
+	// Set the latest block height ProtoRev has encountered.
+	k.SetLatestBlockHeight(ctx, genState.LatestBlockHeight)
+
+	// Configure max pool points per tx. This roughly correlates to the ms of execution time protorev will take
+	// per tx.
+	if err := k.SetMaxPointsPerTx(ctx, genState.MaxPoolPointsPerTx); err != nil {
+		panic(err)
+	}
+
+	// Configure max pool points per block. This roughly correlates to the ms of execution time protorev will
+	// take per block.
+	if err := k.SetMaxPointsPerBlock(ctx, genState.MaxPoolPointsPerBlock); err != nil {
+		panic(err)
+	}
+
+	// Set the number of pool points that have been consumed in the current block.
+	k.SetPointCountForBlock(ctx, genState.PointCountForBlock)
+
+	// Configure the pool weights for genesis. This roughly correlates to the ms of execution time
+	// by pool type.
+	k.SetPoolWeights(ctx, genState.PoolWeights)
+}
+
+// ExportGenesis returns the module's exported genesis. ExportGenesis intentionally ignores a few of the errors thrown
+// by the keeper methods. This is because the keeper methods are only throwing errors if there is an issue unmarshalling
+// or if the value had not been set yet (i.e. developer account address). In that case, we just use the default
+// values defined in genesis.go in types.
+func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
+	genesis := types.DefaultGenesis()
+	// Export the module parameters.
+	genesis.Params = k.GetParams(ctx)
+
+	// Export the pool weights.
+	genesis.PoolWeights = k.GetPoolWeights(ctx)
+
+	// Export the token pair arb routes (hot routes).
+	routes, err := k.GetAllTokenPairArbRoutes(ctx)
+	if err != nil {
+		panic(err)
+	}
+	genesis.TokenPairArbRoutes = routes
+
+	// Export the base denoms used for cyclic route building.
+	baseDenoms, err := k.GetAllBaseDenoms(ctx)
+	if err != nil {
+		panic(err)
+	}
+	genesis.BaseDenoms = baseDenoms
+
+	// Export the developer fees that have been collected.
+	fees, err := k.GetAllDeveloperFees(ctx)
+	if err != nil {
+		panic(err)
+	}
+	genesis.DeveloperFees = fees
+
+	// Export the number of days since module genesis (ignore the case where it has not been set yet).
+	if daysSinceGenesis, err := k.GetDaysSinceModuleGenesis(ctx); err == nil {
+		genesis.DaysSinceModuleGenesis = daysSinceGenesis
+	}
+
+	// Export the developer address (ignore the error in case the developer account was not set yet).
+	if developerAddress, err := k.GetDeveloperAccount(ctx); err == nil {
+		genesis.DeveloperAddress = developerAddress.String()
+	}
+
+	// Export the latest block height (ignore the error in case the latest block height was not set yet).
+	if latestBlockHeight, err := k.GetLatestBlockHeight(ctx); err == nil {
+		genesis.LatestBlockHeight = latestBlockHeight
+	}
+
+	// Export the max pool points per tx (ignore the error in case the max pool points per tx was not set yet).
+	if maxPoolPointsPerTx, err := k.GetMaxPointsPerTx(ctx); err == nil {
+		genesis.MaxPoolPointsPerTx = maxPoolPointsPerTx
+	}
+
+	// Export the max pool points per block (ignore the error in case the max pool points per block was not set yet).
+	if maxPoolPointsPerBlock, err := k.GetMaxPointsPerBlock(ctx); err == nil {
+		genesis.MaxPoolPointsPerBlock = maxPoolPointsPerBlock
+	}
+
+	// Export the number of pool points that have been consumed in the current block (ignore the error in case the
+	// point count for block was not set yet).
+	if pointCount, err := k.GetPointCountForBlock(ctx); err == nil {
+		genesis.PointCountForBlock = pointCount
+	}
+
+	return genesis
+}
diff --git a/x/protorev/keeper/grpc_query.go b/x/protorev/keeper/grpc_query.go
index 3495e88ac..aaacfebbd 100644
--- a/x/protorev/keeper/grpc_query.go
+++ b/x/protorev/keeper/grpc_query.go
@@ -93,7 +93,7 @@ func (q Querier) GetProtoRevStatisticsByRoute(c context.Context, req *types.Quer
 		Profits:        profits,
 		Route:          req.Route,
 	}
-	return &types.QueryGetProtoRevStatisticsByRouteResponse{Statistics: &statistics}, nil
+	return &types.QueryGetProtoRevStatisticsByRouteResponse{Statistics: statistics}, nil
 }
 
 // GetProtoRevAllRouteStatistics queries all of routes that the module has arbitrage
@@ -150,10 +150,7 @@ func (q Querier) GetProtoRevAdminAccount(c context.Context, req *types.QueryGetP
 		return nil, status.Error(codes.InvalidArgument, "invalid request")
 	}
 	ctx := sdk.UnwrapSDKContext(c)
-	adminAccount, err := q.Keeper.GetAdminAccount(ctx)
-	if err != nil {
-		return nil, status.Error(codes.Internal, err.Error())
-	}
+	adminAccount := q.Keeper.GetAdminAccount(ctx)
 
 	return &types.QueryGetProtoRevAdminAccountResponse{AdminAccount: adminAccount.String()}, nil
 }
@@ -231,10 +228,6 @@ func (q Querier) GetProtoRevEnabled(c context.Context, req *types.QueryGetProtoR
 		return nil, status.Error(codes.InvalidArgument, "invalid request")
 	}
 	ctx := sdk.UnwrapSDKContext(c)
-	enabled, err := q.Keeper.GetProtoRevEnabled(ctx)
-	if err != nil {
-		return nil, status.Error(codes.Internal, err.Error())
-	}
 
-	return &types.QueryGetProtoRevEnabledResponse{Enabled: enabled}, nil
+	return &types.QueryGetProtoRevEnabledResponse{Enabled: q.Keeper.GetProtoRevEnabled(ctx)}, nil
 }
diff --git a/x/protorev/keeper/msg_server.go b/x/protorev/keeper/msg_server.go
index da5578bd1..193123624 100644
--- a/x/protorev/keeper/msg_server.go
+++ b/x/protorev/keeper/msg_server.go
@@ -107,7 +107,7 @@ func (m MsgServer) SetPoolWeights(c context.Context, msg *types.MsgSetPoolWeight
 		return nil, err
 	}
 
-	m.k.SetPoolWeights(ctx, *msg.PoolWeights)
+	m.k.SetPoolWeights(ctx, msg.PoolWeights)
 
 	return &types.MsgSetPoolWeightsResponse{}, nil
 }
@@ -147,18 +147,14 @@ func (m MsgServer) SetBaseDenoms(c context.Context, msg *types.MsgSetBaseDenoms)
 	return &types.MsgSetBaseDenomsResponse{}, nil
 }
 
-// AdminCheck ensures that the admin account is set and that the sender is the admin account
+// AdminCheck ensures that the sender is the admin account.
 func (m MsgServer) AdminCheck(ctx sdk.Context, admin string) error {
 	sender, err := sdk.AccAddressFromBech32(admin)
 	if err != nil {
 		return err
 	}
 
-	// If the admin account has not been set, ignore
-	adminAccount, err := m.k.GetAdminAccount(ctx)
-	if err != nil {
-		return err
-	}
+	adminAccount := m.k.GetAdminAccount(ctx)
 
 	// Ensure the admin and sender are the same
 	if !adminAccount.Equals(sender) {
diff --git a/x/protorev/keeper/posthandler.go b/x/protorev/keeper/posthandler.go
index 5a169e4cc..c124f6d6d 100644
--- a/x/protorev/keeper/posthandler.go
+++ b/x/protorev/keeper/posthandler.go
@@ -63,7 +63,7 @@ func (protoRevDec ProtoRevDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
 // AnteHandleCheck checks if the module is enabled and if the number of routes to be processed per block has been reached.
 func (k Keeper) AnteHandleCheck(ctx sdk.Context) error {
 	// Only execute the posthandler if the module is enabled
-	if enabled, err := k.GetProtoRevEnabled(ctx); err != nil || !enabled {
+	if !k.GetProtoRevEnabled(ctx) {
 		return fmt.Errorf("protorev is not enabled")
 	}
 
@@ -100,13 +100,18 @@ func (k Keeper) AnteHandleCheck(ctx sdk.Context) error {
 // ProtoRevTrade wraps around the build routes, iterate routes, and execute trade functionality to execute cyclic arbitrage trades
 // if they exist. It returns an error if there was an issue executing any single trade.
 func (k Keeper) ProtoRevTrade(ctx sdk.Context, swappedPools []SwapToBackrun) error {
+	// Get the total number of pool points that can be consumed in this transaction
+	remainingPoolPoints, err := k.RemainingPoolPointsForTx(ctx)
+	if err != nil {
+		return err
+	}
 	// Iterate and build arbitrage routes for each pool that was swapped on
 	for _, pool := range swappedPools {
 		// Build the routes for the pool that was swapped on
 		routes := k.BuildRoutes(ctx, pool.TokenInDenom, pool.TokenOutDenom, pool.PoolId)
 
 		// Find optimal route (input coin, profit, route) for the given routes
-		maxProfitInputCoin, maxProfitAmount, optimalRoute := k.IterateRoutes(ctx, routes)
+		maxProfitInputCoin, maxProfitAmount, optimalRoute := k.IterateRoutes(ctx, routes, &remainingPoolPoints)
 
 		// The error that returns here is particularly focused on the minting/burning of coins, and the execution of the MultiHopSwapExactAmountIn.
 		if maxProfitAmount.GT(sdk.ZeroInt()) {
diff --git a/x/protorev/keeper/protorev.go b/x/protorev/keeper/protorev.go
index 6318d4257..443884d15 100644
--- a/x/protorev/keeper/protorev.go
+++ b/x/protorev/keeper/protorev.go
@@ -2,7 +2,6 @@ package keeper
 
 import (
 	"fmt"
-	"strconv"
 
 	"github.com/osmosis-labs/osmosis/v15/x/protorev/types"
 
@@ -16,34 +15,34 @@ import (
 // ---------------------- Trading Stores  ---------------------- //
 
 // GetTokenPairArbRoutes returns the token pair arb routes given two denoms
-func (k Keeper) GetTokenPairArbRoutes(ctx sdk.Context, tokenA, tokenB string) (*types.TokenPairArbRoutes, error) {
+func (k Keeper) GetTokenPairArbRoutes(ctx sdk.Context, tokenA, tokenB string) (types.TokenPairArbRoutes, error) {
 	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixTokenPairRoutes)
 	key := types.GetKeyPrefixRouteForTokenPair(tokenA, tokenB)
 
 	bz := store.Get(key)
 	if len(bz) == 0 {
-		return nil, fmt.Errorf("no routes found for token pair %s-%s", tokenA, tokenB)
+		return types.TokenPairArbRoutes{}, fmt.Errorf("no routes found for token pair %s-%s", tokenA, tokenB)
 	}
 
-	tokenPairArbRoutes := &types.TokenPairArbRoutes{}
+	tokenPairArbRoutes := types.TokenPairArbRoutes{}
 	err := tokenPairArbRoutes.Unmarshal(bz)
 	if err != nil {
-		return nil, err
+		return types.TokenPairArbRoutes{}, err
 	}
 
 	return tokenPairArbRoutes, nil
 }
 
 // GetAllTokenPairArbRoutes returns all the token pair arb routes
-func (k Keeper) GetAllTokenPairArbRoutes(ctx sdk.Context) ([]*types.TokenPairArbRoutes, error) {
-	routes := make([]*types.TokenPairArbRoutes, 0)
+func (k Keeper) GetAllTokenPairArbRoutes(ctx sdk.Context) ([]types.TokenPairArbRoutes, error) {
+	routes := make([]types.TokenPairArbRoutes, 0)
 
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixTokenPairRoutes)
 
 	defer iterator.Close()
 	for ; iterator.Valid(); iterator.Next() {
-		tokenPairArbRoutes := &types.TokenPairArbRoutes{}
+		tokenPairArbRoutes := types.TokenPairArbRoutes{}
 		err := tokenPairArbRoutes.Unmarshal(iterator.Value())
 		if err != nil {
 			return nil, err
@@ -56,7 +55,7 @@ func (k Keeper) GetAllTokenPairArbRoutes(ctx sdk.Context) ([]*types.TokenPairArb
 }
 
 // SetTokenPairArbRoutes sets the token pair arb routes given two denoms
-func (k Keeper) SetTokenPairArbRoutes(ctx sdk.Context, tokenA, tokenB string, tokenPair *types.TokenPairArbRoutes) error {
+func (k Keeper) SetTokenPairArbRoutes(ctx sdk.Context, tokenA, tokenB string, tokenPair types.TokenPairArbRoutes) error {
 	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixTokenPairRoutes)
 	key := types.GetKeyPrefixRouteForTokenPair(tokenA, tokenB)
 
@@ -76,18 +75,18 @@ func (k Keeper) DeleteAllTokenPairArbRoutes(ctx sdk.Context) {
 }
 
 // GetAllBaseDenoms returns all of the base denoms (sorted by priority in descending order) used to build cyclic arbitrage routes
-func (k Keeper) GetAllBaseDenoms(ctx sdk.Context) ([]*types.BaseDenom, error) {
-	baseDenoms := make([]*types.BaseDenom, 0)
+func (k Keeper) GetAllBaseDenoms(ctx sdk.Context) ([]types.BaseDenom, error) {
+	baseDenoms := make([]types.BaseDenom, 0)
 
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixBaseDenoms)
 
 	defer iterator.Close()
 	for ; iterator.Valid(); iterator.Next() {
-		baseDenom := &types.BaseDenom{}
+		baseDenom := types.BaseDenom{}
 		err := baseDenom.Unmarshal(iterator.Value())
 		if err != nil {
-			return []*types.BaseDenom{}, err
+			return []types.BaseDenom{}, err
 		}
 
 		baseDenoms = append(baseDenoms, baseDenom)
@@ -98,7 +97,7 @@ func (k Keeper) GetAllBaseDenoms(ctx sdk.Context) ([]*types.BaseDenom, error) {
 
 // SetBaseDenoms sets all of the base denoms used to build cyclic arbitrage routes. The base denoms priority
 // order is going to match the order of the base denoms in the slice.
-func (k Keeper) SetBaseDenoms(ctx sdk.Context, baseDenoms []*types.BaseDenom) error {
+func (k Keeper) SetBaseDenoms(ctx sdk.Context, baseDenoms []types.BaseDenom) error {
 	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixBaseDenoms)
 
 	for i, baseDenom := range baseDenoms {
@@ -242,28 +241,16 @@ func (k Keeper) DeleteDeveloperFees(ctx sdk.Context, denom string) {
 }
 
 // GetProtoRevEnabled returns whether protorev is enabled
-func (k Keeper) GetProtoRevEnabled(ctx sdk.Context) (bool, error) {
-	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixProtoRevEnabled)
-	bz := store.Get(types.KeyPrefixProtoRevEnabled)
-	if bz == nil {
-		// This should never happen as the module is initialized on genesis
-		return false, fmt.Errorf("protorev enabled/disabled configuration has not been set in state")
-	}
-
-	res, err := strconv.ParseBool(string(bz))
-	if err != nil {
-		return false, err
-	}
-
-	return res, nil
+func (k Keeper) GetProtoRevEnabled(ctx sdk.Context) bool {
+	params := k.GetParams(ctx)
+	return params.Enabled
 }
 
 // SetProtoRevEnabled sets whether the protorev post handler is enabled
 func (k Keeper) SetProtoRevEnabled(ctx sdk.Context, enabled bool) {
-	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixProtoRevEnabled)
-	bz := []byte(strconv.FormatBool(enabled))
-	store.Set(types.KeyPrefixProtoRevEnabled, bz)
-	k.SetParams(ctx, types.Params{Enabled: enabled})
+	params := k.GetParams(ctx)
+	params.Enabled = enabled
+	k.SetParams(ctx, params)
 }
 
 // GetPointCountForBlock returns the number of pool points that have been consumed in the current block
@@ -321,20 +308,16 @@ func (k Keeper) SetLatestBlockHeight(ctx sdk.Context, blockHeight uint64) {
 // ---------------------- Admin Stores  ---------------------- //
 
 // GetAdminAccount returns the admin account for protorev
-func (k Keeper) GetAdminAccount(ctx sdk.Context) (sdk.AccAddress, error) {
-	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixAdminAccount)
-	bz := store.Get(types.KeyPrefixAdminAccount)
-	if bz == nil {
-		return nil, fmt.Errorf("admin account not found, it has not been initialized through governance")
-	}
-
-	return sdk.AccAddress(bz), nil
+func (k Keeper) GetAdminAccount(ctx sdk.Context) sdk.AccAddress {
+	params := k.GetParams(ctx)
+	return sdk.MustAccAddressFromBech32(params.Admin)
 }
 
 // SetAdminAccount sets the admin account for protorev
 func (k Keeper) SetAdminAccount(ctx sdk.Context, adminAccount sdk.AccAddress) {
-	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixAdminAccount)
-	store.Set(types.KeyPrefixAdminAccount, adminAccount.Bytes())
+	params := k.GetParams(ctx)
+	params.Admin = adminAccount.String()
+	k.SetParams(ctx, params)
 }
 
 // GetDeveloperAccount returns the developer account for protorev
@@ -412,11 +395,11 @@ func (k Keeper) SetMaxPointsPerBlock(ctx sdk.Context, maxPoints uint64) error {
 
 // GetPoolWeights retrieves the weights of different pool types. The weight of a pool type roughly
 // corresponds to the amount of time it will take to simulate and execute a swap on that pool type (in ms).
-func (k Keeper) GetPoolWeights(ctx sdk.Context) *types.PoolWeights {
+func (k Keeper) GetPoolWeights(ctx sdk.Context) types.PoolWeights {
 	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixPoolWeights)
 	poolWeights := &types.PoolWeights{}
 	osmoutils.MustGet(store, types.KeyPrefixPoolWeights, poolWeights)
-	return poolWeights
+	return *poolWeights
 }
 
 // SetPoolWeights sets the weights of different pool types.
diff --git a/x/protorev/keeper/rebalance.go b/x/protorev/keeper/rebalance.go
index 1501c7a55..a0cc071b0 100644
--- a/x/protorev/keeper/rebalance.go
+++ b/x/protorev/keeper/rebalance.go
@@ -9,26 +9,20 @@ import (
 
 // IterateRoutes checks the profitability of every single route that is passed in
 // and returns the optimal route if there is one
-func (k Keeper) IterateRoutes(ctx sdk.Context, routes []RouteMetaData) (sdk.Coin, sdk.Int, poolmanagertypes.SwapAmountInRoutes) {
+func (k Keeper) IterateRoutes(ctx sdk.Context, routes []RouteMetaData, remainingPoolPoints *uint64) (sdk.Coin, sdk.Int, poolmanagertypes.SwapAmountInRoutes) {
 	var optimalRoute poolmanagertypes.SwapAmountInRoutes
 	var maxProfitInputCoin sdk.Coin
 	maxProfit := sdk.ZeroInt()
 
-	// Get the total number of pool points that can be consumed in this transaction
-	remainingPoolPoints, err := k.RemainingPoolPointsForTx(ctx)
-	if err != nil {
-		return maxProfitInputCoin, maxProfit, optimalRoute
-	}
-
 	// Iterate through the routes and find the optimal route for the given swap
-	for index := 0; index < len(routes) && remainingPoolPoints > 0; index++ {
+	for index := 0; index < len(routes) && *remainingPoolPoints > 0; index++ {
 		// If the route consumes more pool points than we have remaining then we skip it
-		if routes[index].PoolPoints > remainingPoolPoints {
+		if routes[index].PoolPoints > *remainingPoolPoints {
 			continue
 		}
 
 		// Find the max profit for the route if it exists
-		inputCoin, profit, err := k.FindMaxProfitForRoute(ctx, routes[index], &remainingPoolPoints)
+		inputCoin, profit, err := k.FindMaxProfitForRoute(ctx, routes[index], remainingPoolPoints)
 		if err != nil {
 			k.Logger(ctx).Error("Error finding max profit for route: ", err)
 			continue
@@ -124,8 +118,9 @@ func (k Keeper) FindMaxProfitForRoute(ctx sdk.Context, route RouteMetaData, rema
 		return sdk.Coin{}, sdk.ZeroInt(), nil
 	}
 
-	// Increment the number of pool points consumed since we know this route will be profitable
+	// Decrement the number of pool points remaining since we know this route will be profitable
 	*remainingPoolPoints -= route.PoolPoints
+	// Increment the number of pool points consumed since we know this route will be profitable
 	if err := k.IncrementPointCountForBlock(ctx, route.PoolPoints); err != nil {
 		return sdk.Coin{}, sdk.ZeroInt(), err
 	}
diff --git a/x/protorev/keeper/routes.go b/x/protorev/keeper/routes.go
index bc1038157..d5161eafb 100644
--- a/x/protorev/keeper/routes.go
+++ b/x/protorev/keeper/routes.go
@@ -55,7 +55,7 @@ func (k Keeper) BuildHotRoutes(ctx sdk.Context, tokenIn, tokenOut string, poolId
 }
 
 // BuildHotRoute constructs a cyclic arbitrage route given a hot route and swap that should be placed in the hot route.
-func (k Keeper) BuildHotRoute(ctx sdk.Context, route *types.Route, poolId uint64) (RouteMetaData, error) {
+func (k Keeper) BuildHotRoute(ctx sdk.Context, route types.Route, poolId uint64) (RouteMetaData, error) {
 	newRoute := make(poolmanagertypes.SwapAmountInRoutes, 0)
 
 	for _, trade := range route.Trades {
@@ -82,7 +82,7 @@ func (k Keeper) BuildHotRoute(ctx sdk.Context, route *types.Route, poolId uint64
 	return RouteMetaData{
 		Route:      newRoute,
 		PoolPoints: routePoolPoints,
-		StepSize:   *route.StepSize,
+		StepSize:   route.StepSize,
 	}, nil
 }
 
@@ -108,7 +108,7 @@ func (k Keeper) BuildHighestLiquidityRoutes(ctx sdk.Context, tokenIn, tokenOut s
 }
 
 // BuildHighestLiquidityRoute constructs a cyclic arbitrage route that is starts/ends with swapDenom (ex. osmo) given the swap (tokenIn, tokenOut, poolId).
-func (k Keeper) BuildHighestLiquidityRoute(ctx sdk.Context, swapDenom *types.BaseDenom, tokenIn, tokenOut string, poolId uint64) (RouteMetaData, error) {
+func (k Keeper) BuildHighestLiquidityRoute(ctx sdk.Context, swapDenom types.BaseDenom, tokenIn, tokenOut string, poolId uint64) (RouteMetaData, error) {
 	// Create the first swap for the MultiHopSwap Route
 	entryPoolId, err := k.GetPoolForDenomPair(ctx, swapDenom.Denom, tokenOut)
 	if err != nil {
diff --git a/x/protorev/keeper/statistics.go b/x/protorev/keeper/statistics.go
index e54c2d252..7dbc12113 100644
--- a/x/protorev/keeper/statistics.go
+++ b/x/protorev/keeper/statistics.go
@@ -64,8 +64,8 @@ func (k Keeper) GetProfitsByDenom(ctx sdk.Context, denom string) (sdk.Coin, erro
 }
 
 // GetAllProfits returns all of the profits made by the ProtoRev module.
-func (k Keeper) GetAllProfits(ctx sdk.Context) []*sdk.Coin {
-	profits := make([]*sdk.Coin, 0)
+func (k Keeper) GetAllProfits(ctx sdk.Context) []sdk.Coin {
+	profits := make([]sdk.Coin, 0)
 
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefixProfitByDenom)
@@ -75,7 +75,7 @@ func (k Keeper) GetAllProfits(ctx sdk.Context) []*sdk.Coin {
 		bz := iterator.Value()
 		profit := sdk.Coin{}
 		if err := profit.Unmarshal(bz); err == nil {
-			profits = append(profits, &profit)
+			profits = append(profits, profit)
 		}
 	}
 
@@ -174,8 +174,8 @@ func (k Keeper) GetProfitsByRoute(ctx sdk.Context, route []uint64, denom string)
 }
 
 // GetAllProfitsByRoute returns all of the profits made by the ProtoRev module for the given route
-func (k Keeper) GetAllProfitsByRoute(ctx sdk.Context, route []uint64) []*sdk.Coin {
-	profits := make([]*sdk.Coin, 0)
+func (k Keeper) GetAllProfitsByRoute(ctx sdk.Context, route []uint64) []sdk.Coin {
+	profits := make([]sdk.Coin, 0)
 
 	store := ctx.KVStore(k.storeKey)
 	prefix := append(types.KeyPrefixProfitsByRoute, types.GetKeyPrefixProfitsByRoute(route, "")...)
@@ -186,7 +186,7 @@ func (k Keeper) GetAllProfitsByRoute(ctx sdk.Context, route []uint64) []*sdk.Coi
 		bz := iterator.Value()
 		profit := sdk.Coin{}
 		if err := profit.Unmarshal(bz); err == nil {
-			profits = append(profits, &profit)
+			profits = append(profits, profit)
 		}
 	}
 
diff --git a/x/protorev/module.go b/x/protorev/module.go
index 88aac00ec..a0d3cfd53 100644
--- a/x/protorev/module.go
+++ b/x/protorev/module.go
@@ -151,14 +151,14 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.Ra
 	// Initialize global index to index in genesis state
 	cdc.MustUnmarshalJSON(gs, &genState)
 
-	InitGenesis(ctx, am.keeper, genState)
+	am.keeper.InitGenesis(ctx, genState)
 
 	return []abci.ValidatorUpdate{}
 }
 
 // ExportGenesis returns the module's exported genesis state as raw JSON bytes.
 func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
-	genState := ExportGenesis(ctx, am.keeper)
+	genState := am.keeper.ExportGenesis(ctx)
 	return cdc.MustMarshalJSON(genState)
 }
 
diff --git a/x/protorev/protorev.md b/x/protorev/protorev.md
index e2defdbb4..c09a17038 100644
--- a/x/protorev/protorev.md
+++ b/x/protorev/protorev.md
@@ -22,7 +22,7 @@ For ecosystem context about the purpose of the module, please see the ProtoRev g
 
 Cyclic arbitrage is a series of swaps that results in more of the same asset that was initially swapped in. An example of this is as follows:
 
-Assume there exists three pools with the following asset pairs:
+Assume there exist three pools with the following asset pairs:
 
 ```bash
 1. A/B
@@ -80,16 +80,14 @@ The `x/protorev` module keeps the following objects in state:
 | ProfitsByDenom | Tracks the profits protorev has made | []byte{5} + []byte{tokenDenom} | []byte{sdk.Coin} | KV |
 | TradesByRoute | Tracks the number of trades the module has executed on a given route | []byte{6} + []byte{route} | []byte{numberOfTrades} | KV |
 | ProfitsByRoute | Tracks the profits the module has accumulated after trading on a given route | []byte{7} + []byte{route} | []byte{sdk.Coin} | KV |
-| ProtoRevEnabled | Tracks whether the protorev module is enabled | []byte{8} | []byte{bool} | KV |
-| AdminAccount | Tracks the admin account for protorev | []byte{9} | []byte{sdk.AccAddress} | KV |
-| DeveloperAccount | Tracks the developer account for protorev | []byte{10} | []byte{sdk.AccAddress} | KV |
-| DaysSinceModuleGenesis | Tracks the number of days since the module was initialized. Used to track profits that can be withdrawn by the developer account | []byte{11} | []byte{uint} | KV |
-| DeveloperFees | Tracks the profits that the developer account can withdraw | []byte{12} + []byte{tokenDenom} | []byte{sdk.Coin} | KV |
-| MaxPoolPointsPerTx | Tracks the maximum number of pool points that can be consumed per tx | [[]byte{12} | []byte{uint64} | KV |
-| MaxPoolPointsPerBlock | Tracks the maximum number of pool points that can be consumed per block | []byte{13} | []byte{uint64} | KV |
-| PoolPointCountForBlock | Tracks the number of pool points that have been consumed in this block | []byte{15} | []byte{uint64} | KV |
-| LatestBlockHeight | Tracks the latest recorded block height | []byte{16} | []byte{uint64} | KV |
-| PoolWeights | Tracks the weights (pool points) of the different pool types | []byte{17} | []byte{PoolWeights} | KV |
+| DeveloperAccount | Tracks the developer account for protorev | []byte{8} | []byte{sdk.AccAddress} | KV |
+| DaysSinceModuleGenesis | Tracks the number of days since the module was initialized. Used to track profits that can be withdrawn by the developer account | []byte{9} | []byte{uint} | KV |
+| DeveloperFees | Tracks the profits that the developer account can withdraw | []byte{10} + []byte{tokenDenom} | []byte{sdk.Coin} | KV |
+| MaxPoolPointsPerTx | Tracks the maximum number of pool points that can be consumed per tx | []byte{11} | []byte{uint64} | KV |
+| MaxPoolPointsPerBlock | Tracks the maximum number of pool points that can be consumed per block | []byte{12} | []byte{uint64} | KV |
+| PoolPointCountForBlock | Tracks the number of pool points that have been consumed in this block | []byte{13} | []byte{uint64} | KV |
+| LatestBlockHeight | Tracks the latest recorded block height | []byte{14} | []byte{uint64} | KV |
+| PoolWeights | Tracks the weights (pool points) of the different pool types | []byte{15} | []byte{PoolWeights} | KV |
 
 ### TokenPairArbRoutes
 
@@ -237,7 +235,7 @@ There are two primary methods for route generation: **Highest Liquidity Pools**
 
 ### Highest Liquidity Pool Method
 
-The highest liquidity pool method will always create cyclic arbitrage routes that have three pools. The routes that are created will always start and end with one of the denominations that are stored in BaseDenoms. The pooled swapped against that the `postHandler` processes will always be the 2nd pool in the three-pool cyclic arbitrage route. 
+The highest liquidity pool method will always create cyclic arbitrage routes that have three pools. The routes that are created will always start and end with one of the denominations that are stored in BaseDenoms. The pool swapped against that the `postHandler` processes will always be the 2nd pool in the three-pool cyclic arbitrage route. 
 
 **Highest Liquidity Pools:** Updated via the weekly epoch, the module iterates through all the pools and stores the highest liquidity pool for every asset that pairs with any of the base denominations the module stores (for example, the osmo/juno key will have a single pool id stored, that pool id having the most liquidity out of all the osmo/juno pools). New base denominations can be added or removed on an as needed basis by the admin account. A base denomination is just another way of describing the denomination we want to use for cyclic arbitrage. This store is then used to create routes at runtime after analyzing a swap. This store is updated through the `epoch` hook and when the admin account submits a `MsgSetBaseDenoms` tx.
 
diff --git a/x/protorev/types/genesis.go b/x/protorev/types/genesis.go
index c2cdd0307..0d6afa622 100644
--- a/x/protorev/types/genesis.go
+++ b/x/protorev/types/genesis.go
@@ -1,19 +1,91 @@
 package types
 
-type TokenPair struct {
-	TokenA string
-	TokenB string
-}
+import (
+	sdk "github.com/cosmos/cosmos-sdk/types"
+)
+
+var (
+	// Configuration of the default genesis state for the module.
+	DefaultTokenPairArbRoutes = []TokenPairArbRoutes{}
+	// Configure the initial base denoms used for cyclic route building. The order of the list of base
+	// denoms is the order in which routes will be prioritized i.e. routes will be built and simulated in a
+	// first come first serve basis that is based on the order of the base denoms.
+	DefaultBaseDenoms = []BaseDenom{
+		{
+			Denom:    OsmosisDenomination,
+			StepSize: sdk.NewInt(1_000_000),
+		},
+	}
+	DefaultPoolWeights = PoolWeights{
+		StableWeight:       5, // it takes around 5 ms to simulate and execute a stable swap
+		BalancerWeight:     2, // it takes around 2 ms to simulate and execute a balancer swap
+		ConcentratedWeight: 2, // it takes around 2 ms to simulate and execute a concentrated swap
+	}
+	DefaultDaysSinceModuleGenesis    = uint64(0)
+	DefaultDeveloperFees             = []sdk.Coin{}
+	DefaultLatestBlockHeight         = uint64(0)
+	DefaultDeveloperAddress          = ""
+	DefaultMaxPoolPointsPerBlock     = uint64(100)
+	DefaultMaxPoolPointsPerTx        = uint64(18)
+	DefaultPoolPointsConsumedInBlock = uint64(0)
+)
 
 // DefaultGenesis returns the default genesis state
 func DefaultGenesis() *GenesisState {
 	return &GenesisState{
-		Params: DefaultParams(),
+		Params:                 DefaultParams(),
+		TokenPairArbRoutes:     DefaultTokenPairArbRoutes,
+		BaseDenoms:             DefaultBaseDenoms,
+		PoolWeights:            DefaultPoolWeights,
+		DaysSinceModuleGenesis: DefaultDaysSinceModuleGenesis,
+		DeveloperFees:          DefaultDeveloperFees,
+		DeveloperAddress:       DefaultDeveloperAddress,
+		LatestBlockHeight:      DefaultLatestBlockHeight,
+		MaxPoolPointsPerBlock:  DefaultMaxPoolPointsPerBlock,
+		MaxPoolPointsPerTx:     DefaultMaxPoolPointsPerTx,
+		PointCountForBlock:     DefaultPoolPointsConsumedInBlock,
 	}
 }
 
 // Validate performs basic genesis state validation returning an error upon any failure.
 func (gs GenesisState) Validate() error {
+	// Validate the token pair arb routes
+	if err := ValidateTokenPairArbRoutes(gs.TokenPairArbRoutes); err != nil {
+		return err
+	}
+
+	// Validate the base denoms
+	if err := ValidateBaseDenoms(gs.BaseDenoms); err != nil {
+		return err
+	}
+
+	// Validate the pool weights
+	if err := gs.PoolWeights.Validate(); err != nil {
+		return err
+	}
+
+	// Validate the developer fees
+	if err := ValidateDeveloperFees(gs.DeveloperFees); err != nil {
+		return err
+	}
+
+	// Validate the developer address if it is set
+	if gs.DeveloperAddress != "" {
+		if _, err := sdk.AccAddressFromBech32(gs.DeveloperAddress); err != nil {
+			return err
+		}
+	}
+
+	// Validate the max pool points per block
+	if err := ValidateMaxPoolPointsPerBlock(gs.MaxPoolPointsPerBlock); err != nil {
+		return err
+	}
+
+	// Validate the max pool points per tx
+	if err := ValidateMaxPoolPointsPerTx(gs.MaxPoolPointsPerTx); err != nil {
+		return err
+	}
+
 	return gs.Params.Validate()
 }
 
diff --git a/x/protorev/types/genesis.pb.go b/x/protorev/types/genesis.pb.go
index 81b81541c..1795f0d77 100644
--- a/x/protorev/types/genesis.pb.go
+++ b/x/protorev/types/genesis.pb.go
@@ -5,6 +5,8 @@ package types
 
 import (
 	fmt "fmt"
+	_ "github.com/cosmos/cosmos-proto"
+	types "github.com/cosmos/cosmos-sdk/types"
 	_ "github.com/gogo/protobuf/gogoproto"
 	proto "github.com/gogo/protobuf/proto"
 	io "io"
@@ -25,8 +27,32 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // GenesisState defines the protorev module's genesis state.
 type GenesisState struct {
-	// Module Parameters
+	// Parameters for the protorev module.
 	Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
+	// Token pair arb routes for the protorev module (hot routes).
+	TokenPairArbRoutes []TokenPairArbRoutes `protobuf:"bytes,2,rep,name=token_pair_arb_routes,json=tokenPairArbRoutes,proto3" json:"token_pair_arb_routes" yaml:"token_pair_arb_routes"`
+	// The base denominations being used to create cyclic arbitrage routes via the
+	// highest liquidity method.
+	BaseDenoms []BaseDenom `protobuf:"bytes,3,rep,name=base_denoms,json=baseDenoms,proto3" json:"base_denoms" yaml:"base_denoms"`
+	// The pool weights that are being used to calculate the weight (compute cost)
+	// of each route.
+	PoolWeights PoolWeights `protobuf:"bytes,4,opt,name=pool_weights,json=poolWeights,proto3" json:"pool_weights" yaml:"pool_weights"`
+	// The number of days since module genesis.
+	DaysSinceModuleGenesis uint64 `protobuf:"varint,5,opt,name=days_since_module_genesis,json=daysSinceModuleGenesis,proto3" json:"days_since_module_genesis,omitempty" yaml:"days_since_module_genesis"`
+	// The fees the developer account has accumulated over time.
+	DeveloperFees []types.Coin `protobuf:"bytes,6,rep,name=developer_fees,json=developerFees,proto3" json:"developer_fees" yaml:"developer_fees"`
+	// The latest block height that the module has processed.
+	LatestBlockHeight uint64 `protobuf:"varint,7,opt,name=latest_block_height,json=latestBlockHeight,proto3" json:"latest_block_height,omitempty" yaml:"latest_block_height"`
+	// The developer account address of the module.
+	DeveloperAddress string `protobuf:"bytes,8,opt,name=developer_address,json=developerAddress,proto3" json:"developer_address,omitempty" yaml:"developer_address"`
+	// Max pool points per block i.e. the maximum compute time (in ms)
+	// that protorev can use per block.
+	MaxPoolPointsPerBlock uint64 `protobuf:"varint,9,opt,name=max_pool_points_per_block,json=maxPoolPointsPerBlock,proto3" json:"max_pool_points_per_block,omitempty" yaml:"max_pool_points_per_block"`
+	// Max pool points per tx i.e. the maximum compute time (in ms) that
+	// protorev can use per tx.
+	MaxPoolPointsPerTx uint64 `protobuf:"varint,10,opt,name=max_pool_points_per_tx,json=maxPoolPointsPerTx,proto3" json:"max_pool_points_per_tx,omitempty" yaml:"max_pool_points_per_tx"`
+	// The number of pool points that have been consumed in the current block.
+	PointCountForBlock uint64 `protobuf:"varint,11,opt,name=point_count_for_block,json=pointCountForBlock,proto3" json:"point_count_for_block,omitempty" yaml:"point_count_for_block"`
 }
 
 func (m *GenesisState) Reset()         { *m = GenesisState{} }
@@ -69,6 +95,76 @@ func (m *GenesisState) GetParams() Params {
 	return Params{}
 }
 
+func (m *GenesisState) GetTokenPairArbRoutes() []TokenPairArbRoutes {
+	if m != nil {
+		return m.TokenPairArbRoutes
+	}
+	return nil
+}
+
+func (m *GenesisState) GetBaseDenoms() []BaseDenom {
+	if m != nil {
+		return m.BaseDenoms
+	}
+	return nil
+}
+
+func (m *GenesisState) GetPoolWeights() PoolWeights {
+	if m != nil {
+		return m.PoolWeights
+	}
+	return PoolWeights{}
+}
+
+func (m *GenesisState) GetDaysSinceModuleGenesis() uint64 {
+	if m != nil {
+		return m.DaysSinceModuleGenesis
+	}
+	return 0
+}
+
+func (m *GenesisState) GetDeveloperFees() []types.Coin {
+	if m != nil {
+		return m.DeveloperFees
+	}
+	return nil
+}
+
+func (m *GenesisState) GetLatestBlockHeight() uint64 {
+	if m != nil {
+		return m.LatestBlockHeight
+	}
+	return 0
+}
+
+func (m *GenesisState) GetDeveloperAddress() string {
+	if m != nil {
+		return m.DeveloperAddress
+	}
+	return ""
+}
+
+func (m *GenesisState) GetMaxPoolPointsPerBlock() uint64 {
+	if m != nil {
+		return m.MaxPoolPointsPerBlock
+	}
+	return 0
+}
+
+func (m *GenesisState) GetMaxPoolPointsPerTx() uint64 {
+	if m != nil {
+		return m.MaxPoolPointsPerTx
+	}
+	return 0
+}
+
+func (m *GenesisState) GetPointCountForBlock() uint64 {
+	if m != nil {
+		return m.PointCountForBlock
+	}
+	return 0
+}
+
 func init() {
 	proto.RegisterType((*GenesisState)(nil), "osmosis.protorev.v1beta1.GenesisState")
 }
@@ -78,21 +174,49 @@ func init() {
 }
 
 var fileDescriptor_3c77fc2da5752af2 = []byte{
-	// 212 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xcb, 0x2f, 0xce, 0xcd,
-	0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x2f, 0x4a, 0x2d, 0xd3, 0x2f, 0x33, 0x4c,
-	0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x03, 0x4b, 0x08,
-	0x49, 0x40, 0xd5, 0xe9, 0xc1, 0xd4, 0xe9, 0x41, 0xd5, 0x49, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83,
-	0x45, 0xf5, 0x41, 0x2c, 0x88, 0x02, 0x29, 0x75, 0x9c, 0xe6, 0xc2, 0x0d, 0x80, 0x28, 0x54, 0xc5,
-	0xad, 0x30, 0xb1, 0x28, 0x31, 0x17, 0x6a, 0xa1, 0x92, 0x1f, 0x17, 0x8f, 0x3b, 0xc4, 0x41, 0xc1,
-	0x25, 0x89, 0x25, 0xa9, 0x42, 0x76, 0x5c, 0x6c, 0x10, 0x79, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x6e,
-	0x23, 0x05, 0x3d, 0x5c, 0x0e, 0xd4, 0x0b, 0x00, 0xab, 0x73, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21,
-	0x08, 0xaa, 0xcb, 0xc9, 0xef, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92,
-	0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x4c,
-	0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xa1, 0x66, 0xea, 0xe6, 0x24,
-	0x26, 0x15, 0xc3, 0x38, 0xfa, 0x65, 0x86, 0xa6, 0xfa, 0x15, 0x08, 0xe7, 0x96, 0x54, 0x16, 0xa4,
-	0x16, 0x27, 0xb1, 0x81, 0xf9, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0xa0, 0x96, 0xcc,
-	0x50, 0x01, 0x00, 0x00,
+	// 660 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xcf, 0x6e, 0xd3, 0x40,
+	0x10, 0xc6, 0x63, 0x5a, 0x4a, 0xbb, 0x29, 0x15, 0xdd, 0x92, 0xca, 0x09, 0xd4, 0x31, 0xa6, 0x85,
+	0x1c, 0xa8, 0xad, 0x16, 0xb8, 0x70, 0x40, 0xaa, 0x8b, 0x0a, 0x17, 0xaa, 0xc8, 0x2d, 0x42, 0x02,
+	0x89, 0x65, 0x9d, 0x6c, 0x53, 0xab, 0xb6, 0xd7, 0xf2, 0x6e, 0x42, 0xfa, 0x00, 0xdc, 0x39, 0xf3,
+	0x1c, 0x3c, 0x44, 0x8f, 0x15, 0x27, 0x4e, 0x11, 0x6a, 0xdf, 0x20, 0x4f, 0x80, 0xf6, 0x4f, 0x92,
+	0x52, 0x62, 0x6e, 0xd9, 0x99, 0xdf, 0x7c, 0xdf, 0xcc, 0xec, 0xc6, 0xe0, 0x11, 0x65, 0x09, 0x65,
+	0x11, 0xf3, 0xb2, 0x9c, 0x72, 0x9a, 0x93, 0x9e, 0xd7, 0xdb, 0x0a, 0x09, 0xc7, 0x5b, 0x5e, 0x87,
+	0xa4, 0x84, 0x45, 0xcc, 0x95, 0x09, 0x68, 0x6a, 0xce, 0x1d, 0x71, 0xae, 0xe6, 0x6a, 0x77, 0x3b,
+	0xb4, 0x43, 0x65, 0xd4, 0x13, 0xbf, 0x14, 0x50, 0x7b, 0x5c, 0xa8, 0x3b, 0x16, 0x50, 0xe0, 0x46,
+	0x31, 0x88, 0x73, 0x9c, 0x68, 0xc3, 0x5a, 0xb5, 0x25, 0x39, 0xa4, 0x8c, 0xd4, 0x41, 0xa7, 0x2c,
+	0x75, 0xf2, 0x42, 0xcc, 0xc8, 0xb8, 0xb8, 0x45, 0xa3, 0x54, 0xe5, 0x9d, 0xef, 0xf3, 0x60, 0xf1,
+	0xb5, 0x1a, 0xe6, 0x80, 0x63, 0x4e, 0xe0, 0x4b, 0x30, 0xa7, 0xb4, 0x4d, 0xc3, 0x36, 0x1a, 0xe5,
+	0x6d, 0xdb, 0x2d, 0x1a, 0xce, 0x6d, 0x4a, 0xce, 0x9f, 0x3d, 0x1b, 0xd4, 0x4b, 0x81, 0xae, 0x82,
+	0x5f, 0x0d, 0x50, 0xe1, 0xf4, 0x84, 0xa4, 0x28, 0xc3, 0x51, 0x8e, 0x70, 0x1e, 0xa2, 0x9c, 0x76,
+	0x39, 0x61, 0xe6, 0x0d, 0x7b, 0xa6, 0x51, 0xde, 0x7e, 0x52, 0xac, 0x77, 0x28, 0xca, 0x9a, 0x38,
+	0xca, 0x77, 0xf2, 0x30, 0x90, 0x35, 0xfe, 0xba, 0xd0, 0x1e, 0x0e, 0xea, 0xf7, 0x4f, 0x71, 0x12,
+	0xbf, 0x70, 0xa6, 0x0a, 0x3b, 0x01, 0xe4, 0xff, 0x54, 0xc2, 0xcf, 0xa0, 0x2c, 0x66, 0x46, 0x6d,
+	0x92, 0xd2, 0x84, 0x99, 0x33, 0xd2, 0xfc, 0x61, 0xb1, 0xb9, 0x8f, 0x19, 0x79, 0x25, 0x58, 0xbf,
+	0xa6, 0x3d, 0xa1, 0xf2, 0xbc, 0xa2, 0xe2, 0x04, 0x20, 0x1c, 0x61, 0x0c, 0x12, 0xb0, 0x98, 0x51,
+	0x1a, 0xa3, 0x2f, 0x24, 0xea, 0x1c, 0x73, 0x66, 0xce, 0xca, 0x7d, 0x6d, 0xfc, 0x67, 0x5f, 0x94,
+	0xc6, 0xef, 0x15, 0xec, 0xdf, 0xd3, 0x26, 0x2b, 0xca, 0xe4, 0xaa, 0x90, 0x13, 0x94, 0xb3, 0x09,
+	0x09, 0x11, 0xa8, 0xb6, 0xf1, 0x29, 0x43, 0x2c, 0x4a, 0x5b, 0x04, 0x25, 0xb4, 0xdd, 0x8d, 0x09,
+	0xd2, 0xef, 0xcf, 0xbc, 0x69, 0x1b, 0x8d, 0x59, 0x7f, 0x7d, 0x38, 0xa8, 0xdb, 0x4a, 0xa8, 0x10,
+	0x75, 0x82, 0x55, 0x91, 0x3b, 0x10, 0xa9, 0xb7, 0x32, 0xa3, 0xaf, 0x1d, 0x22, 0xb0, 0xd4, 0x26,
+	0x3d, 0x12, 0xd3, 0x8c, 0xe4, 0xe8, 0x88, 0x10, 0x66, 0xce, 0xc9, 0x65, 0x55, 0x5d, 0xfd, 0x92,
+	0xc4, 0xcc, 0xe3, 0x21, 0x76, 0x69, 0x94, 0xfa, 0x6b, 0xba, 0xfb, 0x8a, 0x36, 0xfd, 0xab, 0xdc,
+	0x09, 0x6e, 0x8f, 0x03, 0x7b, 0x84, 0x30, 0xb8, 0x0f, 0x56, 0x62, 0xcc, 0x09, 0xe3, 0x28, 0x8c,
+	0x69, 0xeb, 0x04, 0x1d, 0xcb, 0xc9, 0xcc, 0x5b, 0xb2, 0x77, 0x6b, 0x38, 0xa8, 0xd7, 0x94, 0xcc,
+	0x14, 0xc8, 0x09, 0x96, 0x55, 0xd4, 0x17, 0xc1, 0x37, 0x32, 0x06, 0x3f, 0x82, 0xe5, 0x89, 0x23,
+	0x6e, 0xb7, 0x73, 0xc2, 0x98, 0x39, 0x6f, 0x1b, 0x8d, 0x05, 0xdf, 0x1d, 0x0e, 0xea, 0xe6, 0xf5,
+	0xa6, 0x34, 0xe2, 0xfc, 0xfc, 0xb1, 0xb9, 0xa4, 0x47, 0xda, 0x51, 0xa1, 0xe0, 0xce, 0x98, 0xd2,
+	0x11, 0xf8, 0x09, 0x54, 0x13, 0xdc, 0x47, 0xf2, 0x42, 0x32, 0x1a, 0xa5, 0x9c, 0x21, 0xa1, 0x21,
+	0x9b, 0x32, 0x17, 0xae, 0xaf, 0xbb, 0x10, 0x75, 0x82, 0x4a, 0x82, 0xfb, 0xe2, 0xc6, 0x9b, 0x32,
+	0xd3, 0x24, 0xb9, 0x1c, 0x01, 0xbe, 0x03, 0xab, 0xd3, 0x8a, 0x78, 0xdf, 0x04, 0x52, 0xfc, 0xc1,
+	0x70, 0x50, 0x5f, 0x2b, 0x16, 0xe7, 0x7d, 0x27, 0x80, 0xd7, 0x95, 0x0f, 0xfb, 0xf0, 0x00, 0x54,
+	0x24, 0x85, 0x5a, 0xb4, 0x9b, 0x72, 0x74, 0x44, 0x47, 0x2d, 0x97, 0xa5, 0xaa, 0x3d, 0xf9, 0x0f,
+	0x4d, 0xc5, 0x9c, 0x00, 0xca, 0xf8, 0xae, 0x08, 0xef, 0x51, 0xd5, 0xab, 0xbf, 0x7f, 0x76, 0x61,
+	0x19, 0xe7, 0x17, 0x96, 0xf1, 0xfb, 0xc2, 0x32, 0xbe, 0x5d, 0x5a, 0xa5, 0xf3, 0x4b, 0xab, 0xf4,
+	0xeb, 0xd2, 0x2a, 0x7d, 0x78, 0xd6, 0x89, 0xf8, 0x71, 0x37, 0x74, 0x5b, 0x34, 0xf1, 0xf4, 0x7b,
+	0xdf, 0x8c, 0x71, 0xc8, 0x46, 0x07, 0xaf, 0xb7, 0xf5, 0xdc, 0xeb, 0x4f, 0x3e, 0x5b, 0xfc, 0x34,
+	0x23, 0x2c, 0x9c, 0x93, 0xe7, 0xa7, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x40, 0xe7, 0x7a, 0x25,
+	0x58, 0x05, 0x00, 0x00,
 }
 
 func (m *GenesisState) Marshal() (dAtA []byte, err error) {
@@ -115,6 +239,90 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if m.PointCountForBlock != 0 {
+		i = encodeVarintGenesis(dAtA, i, uint64(m.PointCountForBlock))
+		i--
+		dAtA[i] = 0x58
+	}
+	if m.MaxPoolPointsPerTx != 0 {
+		i = encodeVarintGenesis(dAtA, i, uint64(m.MaxPoolPointsPerTx))
+		i--
+		dAtA[i] = 0x50
+	}
+	if m.MaxPoolPointsPerBlock != 0 {
+		i = encodeVarintGenesis(dAtA, i, uint64(m.MaxPoolPointsPerBlock))
+		i--
+		dAtA[i] = 0x48
+	}
+	if len(m.DeveloperAddress) > 0 {
+		i -= len(m.DeveloperAddress)
+		copy(dAtA[i:], m.DeveloperAddress)
+		i = encodeVarintGenesis(dAtA, i, uint64(len(m.DeveloperAddress)))
+		i--
+		dAtA[i] = 0x42
+	}
+	if m.LatestBlockHeight != 0 {
+		i = encodeVarintGenesis(dAtA, i, uint64(m.LatestBlockHeight))
+		i--
+		dAtA[i] = 0x38
+	}
+	if len(m.DeveloperFees) > 0 {
+		for iNdEx := len(m.DeveloperFees) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.DeveloperFees[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintGenesis(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x32
+		}
+	}
+	if m.DaysSinceModuleGenesis != 0 {
+		i = encodeVarintGenesis(dAtA, i, uint64(m.DaysSinceModuleGenesis))
+		i--
+		dAtA[i] = 0x28
+	}
+	{
+		size, err := m.PoolWeights.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
+		}
+		i -= size
+		i = encodeVarintGenesis(dAtA, i, uint64(size))
+	}
+	i--
+	dAtA[i] = 0x22
+	if len(m.BaseDenoms) > 0 {
+		for iNdEx := len(m.BaseDenoms) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.BaseDenoms[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintGenesis(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x1a
+		}
+	}
+	if len(m.TokenPairArbRoutes) > 0 {
+		for iNdEx := len(m.TokenPairArbRoutes) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.TokenPairArbRoutes[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintGenesis(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x12
+		}
+	}
 	{
 		size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
 		if err != nil {
@@ -147,6 +355,45 @@ func (m *GenesisState) Size() (n int) {
 	_ = l
 	l = m.Params.Size()
 	n += 1 + l + sovGenesis(uint64(l))
+	if len(m.TokenPairArbRoutes) > 0 {
+		for _, e := range m.TokenPairArbRoutes {
+			l = e.Size()
+			n += 1 + l + sovGenesis(uint64(l))
+		}
+	}
+	if len(m.BaseDenoms) > 0 {
+		for _, e := range m.BaseDenoms {
+			l = e.Size()
+			n += 1 + l + sovGenesis(uint64(l))
+		}
+	}
+	l = m.PoolWeights.Size()
+	n += 1 + l + sovGenesis(uint64(l))
+	if m.DaysSinceModuleGenesis != 0 {
+		n += 1 + sovGenesis(uint64(m.DaysSinceModuleGenesis))
+	}
+	if len(m.DeveloperFees) > 0 {
+		for _, e := range m.DeveloperFees {
+			l = e.Size()
+			n += 1 + l + sovGenesis(uint64(l))
+		}
+	}
+	if m.LatestBlockHeight != 0 {
+		n += 1 + sovGenesis(uint64(m.LatestBlockHeight))
+	}
+	l = len(m.DeveloperAddress)
+	if l > 0 {
+		n += 1 + l + sovGenesis(uint64(l))
+	}
+	if m.MaxPoolPointsPerBlock != 0 {
+		n += 1 + sovGenesis(uint64(m.MaxPoolPointsPerBlock))
+	}
+	if m.MaxPoolPointsPerTx != 0 {
+		n += 1 + sovGenesis(uint64(m.MaxPoolPointsPerTx))
+	}
+	if m.PointCountForBlock != 0 {
+		n += 1 + sovGenesis(uint64(m.PointCountForBlock))
+	}
 	return n
 }
 
@@ -218,6 +465,268 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error {
 				return err
 			}
 			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field TokenPairArbRoutes", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.TokenPairArbRoutes = append(m.TokenPairArbRoutes, TokenPairArbRoutes{})
+			if err := m.TokenPairArbRoutes[len(m.TokenPairArbRoutes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 3:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field BaseDenoms", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.BaseDenoms = append(m.BaseDenoms, BaseDenom{})
+			if err := m.BaseDenoms[len(m.BaseDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 4:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PoolWeights", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.PoolWeights.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 5:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DaysSinceModuleGenesis", wireType)
+			}
+			m.DaysSinceModuleGenesis = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.DaysSinceModuleGenesis |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 6:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DeveloperFees", wireType)
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= int(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			if msglen < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.DeveloperFees = append(m.DeveloperFees, types.Coin{})
+			if err := m.DeveloperFees[len(m.DeveloperFees)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 7:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field LatestBlockHeight", wireType)
+			}
+			m.LatestBlockHeight = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.LatestBlockHeight |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 8:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field DeveloperAddress", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthGenesis
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.DeveloperAddress = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
+		case 9:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxPoolPointsPerBlock", wireType)
+			}
+			m.MaxPoolPointsPerBlock = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.MaxPoolPointsPerBlock |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 10:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field MaxPoolPointsPerTx", wireType)
+			}
+			m.MaxPoolPointsPerTx = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.MaxPoolPointsPerTx |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+		case 11:
+			if wireType != 0 {
+				return fmt.Errorf("proto: wrong wireType = %d for field PointCountForBlock", wireType)
+			}
+			m.PointCountForBlock = 0
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowGenesis
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				m.PointCountForBlock |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
 		default:
 			iNdEx = preIndex
 			skippy, err := skipGenesis(dAtA[iNdEx:])
diff --git a/x/protorev/types/keys.go b/x/protorev/types/keys.go
index 42552f96a..cb4566ad1 100644
--- a/x/protorev/types/keys.go
+++ b/x/protorev/types/keys.go
@@ -27,8 +27,6 @@ const (
 	prefixProfitsByDenom
 	prefixTradesByRoute
 	prefixProfitsByRoute
-	prefixProtoRevEnabled
-	prefixAdminAccount
 	prefixDeveloperAccount
 	prefixDaysSinceGenesis
 	prefixDeveloperFees
@@ -64,12 +62,6 @@ var (
 	KeyPrefixProfitsByRoute = []byte{prefixProfitsByRoute}
 
 	// -------------- Keys for configuration/admin stores -------------- //
-	// KeyPrefixProtoRevEnabled is the prefix for store that keeps track of whether protorev is enabled
-	KeyPrefixProtoRevEnabled = []byte{prefixProtoRevEnabled}
-
-	// KeyPrefixAdminAccount is the prefix for store that keeps track of the admin account
-	KeyPrefixAdminAccount = []byte{prefixAdminAccount}
-
 	// KeyPrefixDeveloperAccount is the prefix for store that keeps track of the developer account
 	KeyPrefixDeveloperAccount = []byte{prefixDeveloperAccount}
 
diff --git a/x/protorev/types/msg.go b/x/protorev/types/msg.go
index c1ce6e9ae..67ddb3357 100644
--- a/x/protorev/types/msg.go
+++ b/x/protorev/types/msg.go
@@ -1,8 +1,6 @@
 package types
 
 import (
-	"fmt"
-
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 )
@@ -27,7 +25,7 @@ const (
 
 // ---------------------- Interface for MsgSetHotRoutes ---------------------- //
 // NewMsgSetHotRoutes creates a new MsgSetHotRoutes instance
-func NewMsgSetHotRoutes(admin string, tokenPairArbRoutes []*TokenPairArbRoutes) *MsgSetHotRoutes {
+func NewMsgSetHotRoutes(admin string, tokenPairArbRoutes []TokenPairArbRoutes) *MsgSetHotRoutes {
 	return &MsgSetHotRoutes{
 		Admin:     admin,
 		HotRoutes: tokenPairArbRoutes,
@@ -47,37 +45,13 @@ func (msg MsgSetHotRoutes) Type() string {
 // ValidateBasic validates the MsgSetHotRoutes
 func (msg MsgSetHotRoutes) ValidateBasic() error {
 	// Account must be a valid bech32 address
-	_, err := sdk.AccAddressFromBech32(msg.Admin)
-	if err != nil {
+	if _, err := sdk.AccAddressFromBech32(msg.Admin); err != nil {
 		return sdkerrors.Wrap(err, "invalid admin address (must be bech32)")
 	}
 
-	if msg.HotRoutes == nil {
-		return fmt.Errorf("hot routes cannot be nil")
-	}
-
-	// Each token pair arb route must be valid
-	seenTokenPairs := make(map[TokenPair]bool)
-	for _, tokenPairArbRoutes := range msg.HotRoutes {
-		if tokenPairArbRoutes == nil {
-			return fmt.Errorf("nil token pair arb routes")
-		}
-
-		// Validate the arb routes
-		if err := tokenPairArbRoutes.Validate(); err != nil {
-			return err
-		}
-
-		tokenPair := TokenPair{
-			TokenA: tokenPairArbRoutes.TokenIn,
-			TokenB: tokenPairArbRoutes.TokenOut,
-		}
-		// Validate that the token pair is unique
-		if _, ok := seenTokenPairs[tokenPair]; ok {
-			return fmt.Errorf("duplicate token pair: %s", tokenPair)
-		}
-
-		seenTokenPairs[tokenPair] = true
+	// Validate the hot routes
+	if err := ValidateTokenPairArbRoutes(msg.HotRoutes); err != nil {
+		return err
 	}
 
 	return nil
@@ -168,8 +142,8 @@ func (msg MsgSetMaxPoolPointsPerTx) ValidateBasic() error {
 	}
 
 	// Max pool points per tx must be in the valid range
-	if msg.MaxPoolPointsPerTx <= 0 || msg.MaxPoolPointsPerTx > MaxPoolPointsPerTx {
-		return fmt.Errorf("max pool points per tx must be in the range (0, %d]", MaxPoolPointsPerTx)
+	if err := ValidateMaxPoolPointsPerTx(msg.MaxPoolPointsPerTx); err != nil {
+		return err
 	}
 
 	return nil
@@ -213,8 +187,8 @@ func (msg MsgSetMaxPoolPointsPerBlock) ValidateBasic() error {
 	}
 
 	// Max pool points per block must be in the valid range
-	if msg.MaxPoolPointsPerBlock <= 0 || msg.MaxPoolPointsPerBlock > MaxPoolPointsPerBlock {
-		return fmt.Errorf("max pool points per block must be in the range (0, %d]", MaxPoolPointsPerBlock)
+	if err := ValidateMaxPoolPointsPerBlock(msg.MaxPoolPointsPerBlock); err != nil {
+		return err
 	}
 
 	return nil
@@ -233,7 +207,7 @@ func (msg MsgSetMaxPoolPointsPerBlock) GetSigners() []sdk.AccAddress {
 
 // ---------------------- Interface for MsgSetPoolWeights ---------------------- //
 // NewMsgSetPoolWeights creates a new MsgSetPoolWeights instance
-func NewMsgSetPoolWeights(admin string, poolWeights *PoolWeights) *MsgSetPoolWeights {
+func NewMsgSetPoolWeights(admin string, poolWeights PoolWeights) *MsgSetPoolWeights {
 	return &MsgSetPoolWeights{
 		Admin:       admin,
 		PoolWeights: poolWeights,
@@ -257,12 +231,8 @@ func (msg MsgSetPoolWeights) ValidateBasic() error {
 		return sdkerrors.Wrap(err, "invalid admin address (must be bech32)")
 	}
 
-	if msg.PoolWeights == nil {
-		return fmt.Errorf("pool weights cannot be nil")
-	}
-
-	if msg.PoolWeights.BalancerWeight == 0 || msg.PoolWeights.StableWeight == 0 || msg.PoolWeights.ConcentratedWeight == 0 {
-		return fmt.Errorf("pool weights cannot be 0")
+	if err := msg.PoolWeights.Validate(); err != nil {
+		return err
 	}
 
 	return nil
@@ -281,7 +251,7 @@ func (msg MsgSetPoolWeights) GetSigners() []sdk.AccAddress {
 
 // ---------------------- Interface for MsgSetBaseDenoms ---------------------- //
 // NewMsgSetBaseDenoms creates a new MsgSetBaseDenoms instance
-func NewMsgSetBaseDenoms(admin string, baseDenoms []*BaseDenom) *MsgSetBaseDenoms {
+func NewMsgSetBaseDenoms(admin string, baseDenoms []BaseDenom) *MsgSetBaseDenoms {
 	return &MsgSetBaseDenoms{
 		Admin:      admin,
 		BaseDenoms: baseDenoms,
@@ -306,28 +276,8 @@ func (msg MsgSetBaseDenoms) ValidateBasic() error {
 	}
 
 	// Check that there is at least one base denom and that first denom is osmo
-	if len(msg.BaseDenoms) == 0 || msg.BaseDenoms[0] == nil || msg.BaseDenoms[0].Denom != OsmosisDenomination {
-		return fmt.Errorf("must have at least one base denom and first base denom must be osmo")
-	}
-
-	// Each base denom must be valid
-	seenBaseDenoms := make(map[string]bool)
-	for _, baseDenom := range msg.BaseDenoms {
-		if baseDenom == nil {
-			return fmt.Errorf("base denom cannot be nil")
-		}
-
-		// Validate the base denom step size
-		if baseDenom.StepSize.LT(sdk.OneInt()) {
-			return fmt.Errorf("base denom step size must be at least 1: got %s", baseDenom)
-		}
-
-		// Validate that the base denom is unique
-		if _, ok := seenBaseDenoms[baseDenom.Denom]; ok {
-			return fmt.Errorf("duplicate base denom: %s", baseDenom)
-		}
-
-		seenBaseDenoms[baseDenom.Denom] = true
+	if err := ValidateBaseDenoms(msg.BaseDenoms); err != nil {
+		return err
 	}
 
 	return nil
diff --git a/x/protorev/types/params.go b/x/protorev/types/params.go
index 73cd8596f..6a3932cfd 100644
--- a/x/protorev/types/params.go
+++ b/x/protorev/types/params.go
@@ -3,13 +3,20 @@ package types
 import (
 	"fmt"
 
+	sdk "github.com/cosmos/cosmos-sdk/types"
 	paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
 )
 
 var (
 	DefaultEnableModule = true
+	// Currently configured to be the Skip dev team's address
+	// See https://github.com/osmosis-labs/osmosis/issues/4349 for more details
+	// Note that governance has full ability to change this live on-chain, and this admin can at most prevent protorev from working.
+	// All the settings manager's controls have limits, so it can't lead to a chain halt, excess processing time or prevention of swaps.
+	DefaultAdminAccount = "osmo17nv67dvc7f8yr00rhgxd688gcn9t9wvhn783z4"
 
 	ParamStoreKeyEnableModule = []byte("EnableProtoRevModule")
+	ParamStoreKeyAdminAccount = []byte("AdminAccount")
 )
 
 // ParamKeyTable the param key table for launch module
@@ -18,26 +25,45 @@ func ParamKeyTable() paramtypes.KeyTable {
 }
 
 // NewParams creates a new Params instance
-func NewParams(enable bool) Params {
+func NewParams(enable bool, admin string) Params {
 	return Params{
 		Enabled: enable,
+		Admin:   admin,
 	}
 }
 
 // DefaultParams returns a default set of parameters
 func DefaultParams() Params {
-	return NewParams(DefaultEnableModule)
+	return NewParams(DefaultEnableModule, DefaultAdminAccount)
 }
 
 // ParamSetPairs get the params.ParamSet
 func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
 	return paramtypes.ParamSetPairs{
 		paramtypes.NewParamSetPair(ParamStoreKeyEnableModule, &p.Enabled, ValidateBoolean),
+		paramtypes.NewParamSetPair(ParamStoreKeyAdminAccount, &p.Admin, ValidateAccount),
 	}
 }
 
 // Validate validates the set of params
 func (p Params) Validate() error {
+	if _, err := sdk.AccAddressFromBech32(p.Admin); err != nil {
+		return fmt.Errorf("invalid admin account address: %s", p.Admin)
+	}
+
+	return nil
+}
+
+func ValidateAccount(i interface{}) error {
+	v, ok := i.(string)
+	if !ok {
+		return fmt.Errorf("invalid parameter type: %T", i)
+	}
+
+	if _, err := sdk.AccAddressFromBech32(v); err != nil {
+		return fmt.Errorf("invalid account address: %s", v)
+	}
+
 	return nil
 }
 
diff --git a/x/protorev/types/params.pb.go b/x/protorev/types/params.pb.go
index 9afd415e1..0a7002f82 100644
--- a/x/protorev/types/params.pb.go
+++ b/x/protorev/types/params.pb.go
@@ -5,6 +5,7 @@ package types
 
 import (
 	fmt "fmt"
+	_ "github.com/cosmos/cosmos-proto"
 	_ "github.com/gogo/protobuf/gogoproto"
 	proto "github.com/gogo/protobuf/proto"
 	io "io"
@@ -25,8 +26,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // Params defines the parameters for the module.
 type Params struct {
-	// Boolean whether the module is going to be enabled
-	Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+	// Boolean whether the protorev module is enabled.
+	Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty" yaml:"enabled"`
+	// The admin account (settings manager) of the protorev module.
+	Admin string `protobuf:"bytes,2,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 }
 
 func (m *Params) Reset()         { *m = Params{} }
@@ -69,6 +72,13 @@ func (m *Params) GetEnabled() bool {
 	return false
 }
 
+func (m *Params) GetAdmin() string {
+	if m != nil {
+		return m.Admin
+	}
+	return ""
+}
+
 func init() {
 	proto.RegisterType((*Params)(nil), "osmosis.protorev.v1beta1.Params")
 }
@@ -78,19 +88,23 @@ func init() {
 }
 
 var fileDescriptor_72168e5a5a65ae7e = []byte{
-	// 177 bytes of a gzipped FileDescriptorProto
+	// 252 bytes of a gzipped FileDescriptorProto
 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xcd, 0x2f, 0xce, 0xcd,
 	0x2f, 0xce, 0x2c, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x2f, 0x4a, 0x2d, 0xd3, 0x2f, 0x33, 0x4c,
 	0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x03, 0x8b, 0x0b, 0x49,
 	0x40, 0x95, 0xe9, 0xc1, 0x94, 0xe9, 0x41, 0x95, 0x49, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x83, 0x45,
-	0xf5, 0x41, 0x2c, 0x88, 0x02, 0x25, 0x25, 0x2e, 0xb6, 0x00, 0xb0, 0x7e, 0x21, 0x09, 0x2e, 0xf6,
-	0xd4, 0xbc, 0xc4, 0xa4, 0x9c, 0xd4, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x18, 0xd7,
-	0xc9, 0xef, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0,
-	0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x4c, 0xd2, 0x33, 0x4b,
-	0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xa1, 0x16, 0xeb, 0xe6, 0x24, 0x26, 0x15, 0xc3,
-	0x38, 0xfa, 0x65, 0x86, 0xa6, 0xfa, 0x15, 0x08, 0x27, 0x97, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1,
-	0x81, 0xf9, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x98, 0x65, 0x45, 0xd3, 0x00, 0x00,
-	0x00,
+	0xf5, 0x41, 0x2c, 0x88, 0x02, 0x29, 0xc9, 0x64, 0xb0, 0x86, 0x78, 0x88, 0x04, 0x84, 0x03, 0x91,
+	0x52, 0x2a, 0xe3, 0x62, 0x0b, 0x00, 0x1b, 0x2d, 0xa4, 0xc3, 0xc5, 0x9e, 0x9a, 0x97, 0x98, 0x94,
+	0x93, 0x9a, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe1, 0x24, 0xf4, 0xe9, 0x9e, 0x3c, 0x5f, 0x65,
+	0x62, 0x6e, 0x8e, 0x95, 0x12, 0x54, 0x42, 0x29, 0x08, 0xa6, 0x44, 0xc8, 0x8e, 0x8b, 0x35, 0x31,
+	0x25, 0x37, 0x33, 0x4f, 0x82, 0x49, 0x81, 0x51, 0x83, 0xd3, 0x49, 0xe3, 0xd3, 0x3d, 0x79, 0x1e,
+	0x88, 0x5a, 0xb0, 0xb0, 0xd2, 0xa5, 0x2d, 0xba, 0x22, 0x50, 0x8b, 0x1c, 0x53, 0x52, 0x8a, 0x52,
+	0x8b, 0x8b, 0x83, 0x4b, 0x8a, 0x32, 0xf3, 0xd2, 0x83, 0x20, 0xda, 0x9c, 0xfc, 0x4e, 0x3c, 0x92,
+	0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c,
+	0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x24, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f,
+	0x39, 0x3f, 0x57, 0x1f, 0xea, 0x4f, 0xdd, 0x9c, 0xc4, 0xa4, 0x62, 0x18, 0x47, 0xbf, 0xcc, 0xd0,
+	0x54, 0xbf, 0x02, 0x11, 0x42, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0xbe, 0x31, 0x20,
+	0x00, 0x00, 0xff, 0xff, 0x08, 0x28, 0xa3, 0x77, 0x42, 0x01, 0x00, 0x00,
 }
 
 func (m *Params) Marshal() (dAtA []byte, err error) {
@@ -113,6 +127,13 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
+	if len(m.Admin) > 0 {
+		i -= len(m.Admin)
+		copy(dAtA[i:], m.Admin)
+		i = encodeVarintParams(dAtA, i, uint64(len(m.Admin)))
+		i--
+		dAtA[i] = 0x12
+	}
 	if m.Enabled {
 		i--
 		if m.Enabled {
@@ -146,6 +167,10 @@ func (m *Params) Size() (n int) {
 	if m.Enabled {
 		n += 2
 	}
+	l = len(m.Admin)
+	if l > 0 {
+		n += 1 + l + sovParams(uint64(l))
+	}
 	return n
 }
 
@@ -204,6 +229,38 @@ func (m *Params) Unmarshal(dAtA []byte) error {
 				}
 			}
 			m.Enabled = bool(v != 0)
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Admin", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return ErrIntOverflowParams
+				}
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				stringLen |= uint64(b&0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			intStringLen := int(stringLen)
+			if intStringLen < 0 {
+				return ErrInvalidLengthParams
+			}
+			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthParams
+			}
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.Admin = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipParams(dAtA[iNdEx:])
diff --git a/x/protorev/types/protorev.pb.go b/x/protorev/types/protorev.pb.go
index 8b0bfe080..498209880 100644
--- a/x/protorev/types/protorev.pb.go
+++ b/x/protorev/types/protorev.pb.go
@@ -29,11 +29,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 // TokenPairArbRoutes tracks all of the hot routes for a given pair of tokens
 type TokenPairArbRoutes struct {
 	// Stores all of the possible hot paths for a given pair of tokens
-	ArbRoutes []*Route `protobuf:"bytes,1,rep,name=arb_routes,json=arbRoutes,proto3" json:"arb_routes,omitempty"`
+	ArbRoutes []Route `protobuf:"bytes,1,rep,name=arb_routes,json=arbRoutes,proto3" json:"arb_routes" yaml:"arb_routes"`
 	// Token denomination of the first asset
-	TokenIn string `protobuf:"bytes,2,opt,name=token_in,json=tokenIn,proto3" json:"token_in,omitempty"`
+	TokenIn string `protobuf:"bytes,2,opt,name=token_in,json=tokenIn,proto3" json:"token_in,omitempty" yaml:"token_in"`
 	// Token denomination of the second asset
-	TokenOut string `protobuf:"bytes,3,opt,name=token_out,json=tokenOut,proto3" json:"token_out,omitempty"`
+	TokenOut string `protobuf:"bytes,3,opt,name=token_out,json=tokenOut,proto3" json:"token_out,omitempty" yaml:"token_out"`
 }
 
 func (m *TokenPairArbRoutes) Reset()         { *m = TokenPairArbRoutes{} }
@@ -69,7 +69,7 @@ func (m *TokenPairArbRoutes) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_TokenPairArbRoutes proto.InternalMessageInfo
 
-func (m *TokenPairArbRoutes) GetArbRoutes() []*Route {
+func (m *TokenPairArbRoutes) GetArbRoutes() []Route {
 	if m != nil {
 		return m.ArbRoutes
 	}
@@ -94,10 +94,10 @@ func (m *TokenPairArbRoutes) GetTokenOut() string {
 type Route struct {
 	// The pool IDs that are travered in the directed cyclic graph (traversed left
 	// -> right)
-	Trades []*Trade `protobuf:"bytes,1,rep,name=trades,proto3" json:"trades,omitempty"`
+	Trades []Trade `protobuf:"bytes,1,rep,name=trades,proto3" json:"trades" yaml:"trades"`
 	// The step size that will be used to find the optimal swap amount in the
 	// binary search
-	StepSize *github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=step_size,json=stepSize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"step_size,omitempty"`
+	StepSize github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=step_size,json=stepSize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"step_size" yaml:"step_size"`
 }
 
 func (m *Route) Reset()         { *m = Route{} }
@@ -133,7 +133,7 @@ func (m *Route) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_Route proto.InternalMessageInfo
 
-func (m *Route) GetTrades() []*Trade {
+func (m *Route) GetTrades() []Trade {
 	if m != nil {
 		return m.Trades
 	}
@@ -142,13 +142,12 @@ func (m *Route) GetTrades() []*Trade {
 
 // Trade is a single trade in a route
 type Trade struct {
-	// The pool IDs that are travered in the directed cyclic graph (traversed left
-	// -> right)
-	Pool uint64 `protobuf:"varint,1,opt,name=pool,proto3" json:"pool,omitempty"`
-	// The denom of token A that is traded
-	TokenIn string `protobuf:"bytes,2,opt,name=token_in,json=tokenIn,proto3" json:"token_in,omitempty"`
-	// The denom of token B that is traded
-	TokenOut string `protobuf:"bytes,3,opt,name=token_out,json=tokenOut,proto3" json:"token_out,omitempty"`
+	// The pool id of the pool that is traded on
+	Pool uint64 `protobuf:"varint,1,opt,name=pool,proto3" json:"pool,omitempty" yaml:"pool"`
+	// The denom of the token that is traded
+	TokenIn string `protobuf:"bytes,2,opt,name=token_in,json=tokenIn,proto3" json:"token_in,omitempty" yaml:"token_in"`
+	// The denom of the token that is received
+	TokenOut string `protobuf:"bytes,3,opt,name=token_out,json=tokenOut,proto3" json:"token_out,omitempty" yaml:"token_out"`
 }
 
 func (m *Trade) Reset()         { *m = Trade{} }
@@ -209,12 +208,12 @@ func (m *Trade) GetTokenOut() string {
 // swap on a given route and the profits from the trades
 type RouteStatistics struct {
 	// profits is the total profit from all trades on this route
-	Profits []*types.Coin `protobuf:"bytes,1,rep,name=profits,proto3" json:"profits,omitempty"`
+	Profits []types.Coin `protobuf:"bytes,1,rep,name=profits,proto3" json:"profits" yaml:"profits"`
 	// number_of_trades is the number of trades the module has executed using this
 	// route
-	NumberOfTrades github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=number_of_trades,json=numberOfTrades,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"number_of_trades"`
+	NumberOfTrades github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=number_of_trades,json=numberOfTrades,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"number_of_trades" yaml:"number_of_trades"`
 	// route is the route that was used (pool ids along the arbitrage route)
-	Route []uint64 `protobuf:"varint,3,rep,packed,name=route,proto3" json:"route,omitempty"`
+	Route []uint64 `protobuf:"varint,3,rep,packed,name=route,proto3" json:"route,omitempty" yaml:"route"`
 }
 
 func (m *RouteStatistics) Reset()         { *m = RouteStatistics{} }
@@ -250,7 +249,7 @@ func (m *RouteStatistics) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_RouteStatistics proto.InternalMessageInfo
 
-func (m *RouteStatistics) GetProfits() []*types.Coin {
+func (m *RouteStatistics) GetProfits() []types.Coin {
 	if m != nil {
 		return m.Profits
 	}
@@ -271,11 +270,11 @@ func (m *RouteStatistics) GetRoute() []uint64 {
 // pool type.
 type PoolWeights struct {
 	// The weight of a stableswap pool
-	StableWeight uint64 `protobuf:"varint,1,opt,name=stable_weight,json=stableWeight,proto3" json:"stable_weight,omitempty"`
+	StableWeight uint64 `protobuf:"varint,1,opt,name=stable_weight,json=stableWeight,proto3" json:"stable_weight,omitempty" yaml:"stable_weight"`
 	// The weight of a balancer pool
-	BalancerWeight uint64 `protobuf:"varint,2,opt,name=balancer_weight,json=balancerWeight,proto3" json:"balancer_weight,omitempty"`
+	BalancerWeight uint64 `protobuf:"varint,2,opt,name=balancer_weight,json=balancerWeight,proto3" json:"balancer_weight,omitempty" yaml:"balancer_weight"`
 	// The weight of a concentrated pool
-	ConcentratedWeight uint64 `protobuf:"varint,3,opt,name=concentrated_weight,json=concentratedWeight,proto3" json:"concentrated_weight,omitempty"`
+	ConcentratedWeight uint64 `protobuf:"varint,3,opt,name=concentrated_weight,json=concentratedWeight,proto3" json:"concentrated_weight,omitempty" yaml:"concentrated_weight"`
 }
 
 func (m *PoolWeights) Reset()         { *m = PoolWeights{} }
@@ -337,10 +336,10 @@ func (m *PoolWeights) GetConcentratedWeight() uint64 {
 // binary search that is used to find the optimal swap amount
 type BaseDenom struct {
 	// The denom i.e. name of the base denom (ex. uosmo)
-	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"`
 	// The step size of the binary search that is used to find the optimal swap
 	// amount
-	StepSize github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=step_size,json=stepSize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"step_size"`
+	StepSize github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=step_size,json=stepSize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"step_size" yaml:"step_size"`
 }
 
 func (m *BaseDenom) Reset()         { *m = BaseDenom{} }
@@ -397,42 +396,49 @@ func init() {
 }
 
 var fileDescriptor_1e9f2391fd9fec01 = []byte{
-	// 546 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0xcd, 0x6e, 0x13, 0x31,
-	0x10, 0xc7, 0xe3, 0x26, 0xfd, 0x58, 0x17, 0x5a, 0x64, 0x7a, 0xd8, 0x14, 0x69, 0x13, 0x05, 0x89,
-	0xe6, 0xd2, 0x5d, 0x85, 0x82, 0x90, 0x38, 0x20, 0x11, 0xb8, 0x54, 0x48, 0xb4, 0xda, 0x46, 0xe2,
-	0xe3, 0xb2, 0xf2, 0x6e, 0x9c, 0xd4, 0x6a, 0xe2, 0x89, 0x6c, 0x27, 0x40, 0x9f, 0x81, 0x03, 0x82,
-	0x17, 0xe0, 0x29, 0x78, 0x86, 0x1e, 0x7b, 0x44, 0x1c, 0x2a, 0x94, 0x5c, 0x78, 0x0c, 0xb4, 0xb6,
-	0x77, 0xdb, 0x4b, 0x25, 0x3e, 0x4e, 0x3b, 0xf3, 0x9f, 0x9f, 0xc7, 0x33, 0xe3, 0xd1, 0xe2, 0x1d,
-	0x50, 0x63, 0x50, 0x5c, 0x45, 0x13, 0x09, 0x1a, 0x24, 0x9b, 0x45, 0xb3, 0x4e, 0xca, 0x34, 0xed,
-	0x94, 0x42, 0x68, 0x0c, 0xe2, 0x3b, 0x30, 0x2c, 0x75, 0x07, 0x6e, 0xd7, 0x33, 0x13, 0x4a, 0x4c,
-	0x20, 0xb2, 0x8e, 0xa5, 0xb6, 0xb7, 0x86, 0x30, 0x04, 0xab, 0xe7, 0x96, 0x53, 0x03, 0xcb, 0x44,
-	0x29, 0x55, 0xac, 0xbc, 0x2e, 0x03, 0x2e, 0x6c, 0xbc, 0xf5, 0x19, 0x61, 0xd2, 0x83, 0x13, 0x26,
-	0x0e, 0x29, 0x97, 0x4f, 0x65, 0x1a, 0xc3, 0x54, 0x33, 0x45, 0x9e, 0x60, 0x4c, 0x65, 0x9a, 0x48,
-	0xe3, 0xf9, 0xa8, 0x59, 0x6d, 0xaf, 0xdf, 0x6f, 0x84, 0xd7, 0x95, 0x15, 0x9a, 0x53, 0xb1, 0x47,
-	0xcb, 0xf3, 0x75, 0xbc, 0xa6, 0xf3, 0xac, 0x09, 0x17, 0xfe, 0x52, 0x13, 0xb5, 0xbd, 0x78, 0xd5,
-	0xf8, 0xfb, 0x82, 0xdc, 0xc1, 0x9e, 0x0d, 0xc1, 0x54, 0xfb, 0x55, 0x13, 0xb3, 0xec, 0xc1, 0x54,
-	0x3f, 0xae, 0xfd, 0xfa, 0xda, 0x40, 0xad, 0x2f, 0x08, 0x2f, 0x9b, 0x44, 0xe4, 0x11, 0x5e, 0xd1,
-	0x92, 0xf6, 0xff, 0xa4, 0x86, 0x5e, 0xce, 0xc5, 0x0e, 0x27, 0x2f, 0xb0, 0xa7, 0x34, 0x9b, 0x24,
-	0x8a, 0x9f, 0x32, 0x5b, 0x41, 0x37, 0x3c, 0xbb, 0x68, 0xa0, 0x1f, 0x17, 0x8d, 0x7b, 0x43, 0xae,
-	0x8f, 0xa7, 0x69, 0x98, 0xc1, 0xd8, 0x4d, 0xd0, 0x7d, 0x76, 0x55, 0xff, 0x24, 0xd2, 0x1f, 0x26,
-	0x4c, 0x85, 0xfb, 0x42, 0xc7, 0x6b, 0x79, 0x82, 0x23, 0x7e, 0xca, 0x5c, 0x55, 0x6f, 0xf0, 0xb2,
-	0xb9, 0x83, 0x10, 0x5c, 0x9b, 0x00, 0x8c, 0x7c, 0xd4, 0x44, 0xed, 0x5a, 0x6c, 0xec, 0xff, 0x6c,
-	0xf8, 0x1b, 0xc2, 0x9b, 0xa6, 0xe1, 0x23, 0x4d, 0x35, 0x57, 0x9a, 0x67, 0x8a, 0xec, 0xe1, 0xd5,
-	0x89, 0x84, 0x01, 0xd7, 0x45, 0xef, 0xf5, 0xd0, 0xbd, 0x77, 0xfe, 0x96, 0x65, 0xdb, 0xcf, 0x80,
-	0x8b, 0xb8, 0x20, 0xc9, 0x6b, 0x7c, 0x4b, 0x4c, 0xc7, 0x29, 0x93, 0x09, 0x0c, 0x12, 0x37, 0xb9,
-	0xcb, 0xee, 0x2b, 0x7f, 0xd1, 0xfd, 0x86, 0xcd, 0x73, 0x30, 0xe8, 0xd9, 0x81, 0x6e, 0xe1, 0x65,
-	0xb3, 0x0d, 0x7e, 0xb5, 0x59, 0x6d, 0xd7, 0x62, 0xeb, 0xb4, 0x3e, 0x22, 0xbc, 0x7e, 0x08, 0x30,
-	0x7a, 0xc5, 0xf8, 0xf0, 0x58, 0x2b, 0x72, 0x17, 0xdf, 0x54, 0x9a, 0xa6, 0x23, 0x96, 0xbc, 0x33,
-	0x8a, 0x9b, 0xd1, 0x0d, 0x2b, 0x5a, 0x8a, 0xec, 0xe0, 0xcd, 0x94, 0x8e, 0xa8, 0xc8, 0x98, 0x2c,
-	0xb0, 0x25, 0x83, 0x6d, 0x14, 0xb2, 0x03, 0x23, 0x7c, 0x3b, 0x03, 0x91, 0x31, 0xa1, 0x25, 0xd5,
-	0xac, 0x5f, 0xc0, 0x55, 0x03, 0x93, 0xab, 0x21, 0x7b, 0xa0, 0x25, 0xb0, 0xd7, 0xa5, 0x8a, 0x3d,
-	0x67, 0x02, 0xc6, 0x79, 0xc5, 0xfd, 0xdc, 0x30, 0x35, 0x78, 0xb1, 0x75, 0xae, 0x5b, 0x8c, 0xca,
-	0xbf, 0x2c, 0x46, 0xf7, 0xe5, 0xd9, 0x3c, 0x40, 0xe7, 0xf3, 0x00, 0xfd, 0x9c, 0x07, 0xe8, 0xd3,
-	0x22, 0xa8, 0x9c, 0x2f, 0x82, 0xca, 0xf7, 0x45, 0x50, 0x79, 0xfb, 0xe0, 0x4a, 0x2e, 0xb7, 0xb2,
-	0xbb, 0x23, 0x9a, 0xaa, 0xc2, 0x89, 0x66, 0x9d, 0x87, 0xd1, 0xfb, 0xcb, 0x3f, 0x81, 0xc9, 0x9e,
-	0xae, 0x18, 0x7f, 0xef, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x54, 0x90, 0x53, 0x97, 0x2a, 0x04,
-	0x00, 0x00,
+	// 661 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xbd, 0x6f, 0xd3, 0x40,
+	0x14, 0xcf, 0x35, 0xe9, 0x47, 0xae, 0x1f, 0x29, 0x6e, 0x29, 0x6e, 0x06, 0x3b, 0x3a, 0xa4, 0x92,
+	0xa5, 0xb6, 0xc2, 0xc7, 0x52, 0x89, 0x01, 0x97, 0xa5, 0x42, 0x6a, 0xab, 0x6b, 0x25, 0x04, 0x8b,
+	0x75, 0x76, 0xae, 0xa9, 0xd5, 0xc4, 0x17, 0xf9, 0x2e, 0x85, 0xf6, 0xaf, 0x60, 0x80, 0x9d, 0xbf,
+	0x84, 0xb9, 0x63, 0xc7, 0x8a, 0xc1, 0x42, 0xe9, 0xc2, 0xec, 0x95, 0x05, 0xf9, 0xee, 0xec, 0x44,
+	0x15, 0x48, 0x30, 0xc0, 0xe4, 0xf7, 0x7e, 0xef, 0xfd, 0x7e, 0xef, 0xde, 0x7b, 0x77, 0x86, 0x8f,
+	0x18, 0x1f, 0x30, 0x1e, 0x71, 0x77, 0x98, 0x30, 0xc1, 0x12, 0x7a, 0xee, 0x9e, 0x77, 0x02, 0x2a,
+	0x48, 0xa7, 0x04, 0x1c, 0x69, 0x18, 0xa6, 0x4e, 0x74, 0x4a, 0x5c, 0x27, 0x36, 0x37, 0x43, 0x19,
+	0xf2, 0x65, 0xc0, 0x55, 0x8e, 0xca, 0x6a, 0xae, 0xf7, 0x58, 0x8f, 0x29, 0x3c, 0xb7, 0x34, 0x6a,
+	0xa9, 0x1c, 0x37, 0x20, 0x9c, 0x96, 0xe5, 0x42, 0x16, 0xc5, 0x2a, 0x8e, 0x6e, 0x00, 0x34, 0x8e,
+	0xd9, 0x19, 0x8d, 0x0f, 0x49, 0x94, 0xbc, 0x48, 0x02, 0xcc, 0x46, 0x82, 0x72, 0xe3, 0x0d, 0x84,
+	0x24, 0x09, 0xfc, 0x44, 0x7a, 0x26, 0x68, 0x55, 0xdb, 0x8b, 0x8f, 0x6d, 0xe7, 0x77, 0xc7, 0x72,
+	0x24, 0xcb, 0xdb, 0xbc, 0x4a, 0xed, 0x4a, 0x96, 0xda, 0xf7, 0x2e, 0xc8, 0xa0, 0xbf, 0x83, 0x26,
+	0x02, 0x08, 0xd7, 0x49, 0x29, 0xed, 0xc0, 0x05, 0x91, 0x17, 0xf4, 0xa3, 0xd8, 0x9c, 0x69, 0x81,
+	0x76, 0xdd, 0x5b, 0xcb, 0x52, 0xbb, 0xa1, 0x38, 0x45, 0x04, 0xe1, 0x79, 0x69, 0xee, 0xc5, 0x46,
+	0x07, 0xd6, 0x15, 0xca, 0x46, 0xc2, 0xac, 0x4a, 0xc2, 0x7a, 0x96, 0xda, 0xab, 0xd3, 0x04, 0x36,
+	0x12, 0x08, 0x2b, 0xd9, 0x83, 0x91, 0xd8, 0xa9, 0x7d, 0xff, 0x6c, 0x03, 0xf4, 0x05, 0xc0, 0x59,
+	0x59, 0xd3, 0xd8, 0x87, 0x73, 0x22, 0x21, 0xdd, 0x3f, 0xe9, 0xe4, 0x38, 0xcf, 0xf3, 0xee, 0xeb,
+	0x4e, 0x96, 0x75, 0x11, 0x49, 0x46, 0x58, 0xab, 0x18, 0x3e, 0xac, 0x73, 0x41, 0x87, 0x3e, 0x8f,
+	0x2e, 0xa9, 0xee, 0xc1, 0xcb, 0x19, 0x5f, 0x53, 0x7b, 0xab, 0x17, 0x89, 0xd3, 0x51, 0xe0, 0x84,
+	0x6c, 0xa0, 0xd7, 0xa3, 0x3f, 0xdb, 0xbc, 0x7b, 0xe6, 0x8a, 0x8b, 0x21, 0xe5, 0xce, 0x5e, 0x2c,
+	0x26, 0x0d, 0x94, 0x42, 0x08, 0x2f, 0xe4, 0xf6, 0x51, 0x74, 0x49, 0x75, 0x03, 0x9f, 0x00, 0x9c,
+	0x95, 0xe7, 0x31, 0x1e, 0xc2, 0xda, 0x90, 0xb1, 0xbe, 0x09, 0x5a, 0xa0, 0x5d, 0xf3, 0x1a, 0x59,
+	0x6a, 0x2f, 0x2a, 0x76, 0x8e, 0x22, 0x2c, 0x83, 0xff, 0x6f, 0xb0, 0x3f, 0x00, 0x6c, 0xc8, 0xc1,
+	0x1e, 0x09, 0x22, 0x22, 0x2e, 0xa2, 0x90, 0x1b, 0xaf, 0xe0, 0xfc, 0x30, 0x61, 0x27, 0x91, 0x28,
+	0x66, 0xbc, 0xe9, 0xe8, 0xdb, 0x99, 0xdf, 0xbc, 0x72, 0xbc, 0xbb, 0x2c, 0x8a, 0xbd, 0x0d, 0x3d,
+	0xdd, 0x15, 0xdd, 0x83, 0xe2, 0x21, 0x5c, 0x28, 0x18, 0x1c, 0xae, 0xc6, 0xa3, 0x41, 0x40, 0x13,
+	0x9f, 0x9d, 0xf8, 0x7a, 0x73, 0xaa, 0xa3, 0xbd, 0xbf, 0x1e, 0xf3, 0x03, 0x55, 0xe4, 0xae, 0x1e,
+	0xc2, 0x2b, 0x0a, 0x3a, 0x38, 0x39, 0x56, 0x4b, 0xdd, 0x82, 0xb3, 0xf2, 0xb6, 0x9a, 0xd5, 0x56,
+	0xb5, 0x5d, 0xf3, 0x56, 0xb3, 0xd4, 0x5e, 0x52, 0x5c, 0x09, 0x23, 0xac, 0xc2, 0x68, 0x0c, 0xe0,
+	0xe2, 0x21, 0x63, 0xfd, 0xd7, 0x34, 0xea, 0x9d, 0x0a, 0x6e, 0x3c, 0x87, 0xcb, 0x5c, 0x90, 0xa0,
+	0x4f, 0xfd, 0x77, 0x12, 0xd1, 0x4b, 0x32, 0xb3, 0xd4, 0x5e, 0x2f, 0x56, 0x3c, 0x15, 0x46, 0x78,
+	0x49, 0xf9, 0x8a, 0x6f, 0xec, 0xc2, 0x46, 0x40, 0xfa, 0x24, 0x0e, 0x69, 0x52, 0x08, 0xcc, 0x48,
+	0x81, 0x66, 0x96, 0xda, 0x1b, 0x4a, 0xe0, 0x4e, 0x02, 0xc2, 0x2b, 0x05, 0xa2, 0x45, 0x0e, 0xe0,
+	0x5a, 0xc8, 0xe2, 0x90, 0xc6, 0x22, 0x21, 0x82, 0x76, 0x0b, 0xa1, 0xaa, 0x14, 0xb2, 0xb2, 0xd4,
+	0x6e, 0x2a, 0xa1, 0x5f, 0x24, 0x21, 0x6c, 0x4c, 0xa3, 0x4a, 0x10, 0x7d, 0x04, 0xb0, 0xee, 0x11,
+	0x4e, 0x5f, 0xd2, 0x98, 0x0d, 0xf2, 0xd1, 0x74, 0x73, 0x43, 0xb6, 0x56, 0x9f, 0x1e, 0x8d, 0x84,
+	0x11, 0x56, 0xe1, 0x7f, 0xfe, 0x2e, 0xbc, 0xfd, 0xab, 0xb1, 0x05, 0xae, 0xc7, 0x16, 0xf8, 0x36,
+	0xb6, 0xc0, 0x87, 0x5b, 0xab, 0x72, 0x7d, 0x6b, 0x55, 0x6e, 0x6e, 0xad, 0xca, 0xdb, 0xa7, 0x53,
+	0xfa, 0xfa, 0x71, 0x6f, 0xf7, 0x49, 0xc0, 0x0b, 0xc7, 0x3d, 0xef, 0x3c, 0x73, 0xdf, 0x4f, 0xfe,
+	0xbc, 0xb2, 0x62, 0x30, 0x27, 0xfd, 0x27, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xec, 0x1d, 0xab,
+	0xff, 0x9a, 0x05, 0x00, 0x00,
 }
 
 func (this *TokenPairArbRoutes) Equal(that interface{}) bool {
@@ -458,7 +464,7 @@ func (this *TokenPairArbRoutes) Equal(that interface{}) bool {
 		return false
 	}
 	for i := range this.ArbRoutes {
-		if !this.ArbRoutes[i].Equal(that1.ArbRoutes[i]) {
+		if !this.ArbRoutes[i].Equal(&that1.ArbRoutes[i]) {
 			return false
 		}
 	}
@@ -493,15 +499,11 @@ func (this *Route) Equal(that interface{}) bool {
 		return false
 	}
 	for i := range this.Trades {
-		if !this.Trades[i].Equal(that1.Trades[i]) {
+		if !this.Trades[i].Equal(&that1.Trades[i]) {
 			return false
 		}
 	}
-	if that1.StepSize == nil {
-		if this.StepSize != nil {
-			return false
-		}
-	} else if !this.StepSize.Equal(*that1.StepSize) {
+	if !this.StepSize.Equal(that1.StepSize) {
 		return false
 	}
 	return true
@@ -607,18 +609,16 @@ func (m *Route) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
-	if m.StepSize != nil {
-		{
-			size := m.StepSize.Size()
-			i -= size
-			if _, err := m.StepSize.MarshalTo(dAtA[i:]); err != nil {
-				return 0, err
-			}
-			i = encodeVarintProtorev(dAtA, i, uint64(size))
+	{
+		size := m.StepSize.Size()
+		i -= size
+		if _, err := m.StepSize.MarshalTo(dAtA[i:]); err != nil {
+			return 0, err
 		}
-		i--
-		dAtA[i] = 0x12
+		i = encodeVarintProtorev(dAtA, i, uint64(size))
 	}
+	i--
+	dAtA[i] = 0x12
 	if len(m.Trades) > 0 {
 		for iNdEx := len(m.Trades) - 1; iNdEx >= 0; iNdEx-- {
 			{
@@ -867,10 +867,8 @@ func (m *Route) Size() (n int) {
 			n += 1 + l + sovProtorev(uint64(l))
 		}
 	}
-	if m.StepSize != nil {
-		l = m.StepSize.Size()
-		n += 1 + l + sovProtorev(uint64(l))
-	}
+	l = m.StepSize.Size()
+	n += 1 + l + sovProtorev(uint64(l))
 	return n
 }
 
@@ -1015,7 +1013,7 @@ func (m *TokenPairArbRoutes) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.ArbRoutes = append(m.ArbRoutes, &Route{})
+			m.ArbRoutes = append(m.ArbRoutes, Route{})
 			if err := m.ArbRoutes[len(m.ArbRoutes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -1163,7 +1161,7 @@ func (m *Route) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Trades = append(m.Trades, &Trade{})
+			m.Trades = append(m.Trades, Trade{})
 			if err := m.Trades[len(m.Trades)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -1198,8 +1196,6 @@ func (m *Route) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			var v github_com_cosmos_cosmos_sdk_types.Int
-			m.StepSize = &v
 			if err := m.StepSize.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -1416,7 +1412,7 @@ func (m *RouteStatistics) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Profits = append(m.Profits, &types.Coin{})
+			m.Profits = append(m.Profits, types.Coin{})
 			if err := m.Profits[len(m.Profits)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
diff --git a/x/protorev/types/query.pb.go b/x/protorev/types/query.pb.go
index ed87fd41f..3e9e0c6dd 100644
--- a/x/protorev/types/query.pb.go
+++ b/x/protorev/types/query.pb.go
@@ -72,7 +72,7 @@ var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo
 // QueryParamsResponse is response type for the Query/Params RPC method.
 type QueryParamsResponse struct {
 	// params holds all the parameters of this module.
-	Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
+	Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params" yaml:"params"`
 }
 
 func (m *QueryParamsResponse) Reset()         { *m = QueryParamsResponse{} }
@@ -157,7 +157,7 @@ var xxx_messageInfo_QueryGetProtoRevNumberOfTradesRequest proto.InternalMessageI
 // Query/GetProtoRevNumberOfTrades RPC method.
 type QueryGetProtoRevNumberOfTradesResponse struct {
 	// number_of_trades is the number of trades the module has executed
-	NumberOfTrades github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=number_of_trades,json=numberOfTrades,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"number_of_trades"`
+	NumberOfTrades github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=number_of_trades,json=numberOfTrades,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"number_of_trades" yaml:"number_of_trades"`
 }
 
 func (m *QueryGetProtoRevNumberOfTradesResponse) Reset() {
@@ -199,7 +199,7 @@ var xxx_messageInfo_QueryGetProtoRevNumberOfTradesResponse proto.InternalMessage
 // Query/GetProtoRevProfitsByDenom RPC method.
 type QueryGetProtoRevProfitsByDenomRequest struct {
 	// denom is the denom to query profits by
-	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
+	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty" yaml:"denom"`
 }
 
 func (m *QueryGetProtoRevProfitsByDenomRequest) Reset()         { *m = QueryGetProtoRevProfitsByDenomRequest{} }
@@ -246,7 +246,7 @@ func (m *QueryGetProtoRevProfitsByDenomRequest) GetDenom() string {
 // Query/GetProtoRevProfitsByDenom RPC method.
 type QueryGetProtoRevProfitsByDenomResponse struct {
 	// profit is the profits of the module by the selected denom
-	Profit *types.Coin `protobuf:"bytes,1,opt,name=profit,proto3" json:"profit,omitempty"`
+	Profit *types.Coin `protobuf:"bytes,1,opt,name=profit,proto3" json:"profit,omitempty" yaml:"profit"`
 }
 
 func (m *QueryGetProtoRevProfitsByDenomResponse) Reset() {
@@ -333,7 +333,7 @@ var xxx_messageInfo_QueryGetProtoRevAllProfitsRequest proto.InternalMessageInfo
 // Query/GetProtoRevAllProfits RPC method.
 type QueryGetProtoRevAllProfitsResponse struct {
 	// profits is a list of all of the profits from the module
-	Profits []*types.Coin `protobuf:"bytes,1,rep,name=profits,proto3" json:"profits,omitempty"`
+	Profits []types.Coin `protobuf:"bytes,1,rep,name=profits,proto3" json:"profits" yaml:"profits"`
 }
 
 func (m *QueryGetProtoRevAllProfitsResponse) Reset()         { *m = QueryGetProtoRevAllProfitsResponse{} }
@@ -369,7 +369,7 @@ func (m *QueryGetProtoRevAllProfitsResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryGetProtoRevAllProfitsResponse proto.InternalMessageInfo
 
-func (m *QueryGetProtoRevAllProfitsResponse) GetProfits() []*types.Coin {
+func (m *QueryGetProtoRevAllProfitsResponse) GetProfits() []types.Coin {
 	if m != nil {
 		return m.Profits
 	}
@@ -380,7 +380,7 @@ func (m *QueryGetProtoRevAllProfitsResponse) GetProfits() []*types.Coin {
 // Query/GetProtoRevStatisticsByRoute RPC method.
 type QueryGetProtoRevStatisticsByRouteRequest struct {
 	// route is the set of pool ids to query statistics by i.e. 1,2,3
-	Route []uint64 `protobuf:"varint,1,rep,packed,name=route,proto3" json:"route,omitempty"`
+	Route []uint64 `protobuf:"varint,1,rep,packed,name=route,proto3" json:"route,omitempty" yaml:"route"`
 }
 
 func (m *QueryGetProtoRevStatisticsByRouteRequest) Reset() {
@@ -430,7 +430,7 @@ func (m *QueryGetProtoRevStatisticsByRouteRequest) GetRoute() []uint64 {
 type QueryGetProtoRevStatisticsByRouteResponse struct {
 	// statistics contains the number of trades the module has executed after a
 	// swap on a given pool and the profits from the trades
-	Statistics *RouteStatistics `protobuf:"bytes,1,opt,name=statistics,proto3" json:"statistics,omitempty"`
+	Statistics RouteStatistics `protobuf:"bytes,1,opt,name=statistics,proto3" json:"statistics" yaml:"statistics"`
 }
 
 func (m *QueryGetProtoRevStatisticsByRouteResponse) Reset() {
@@ -470,11 +470,11 @@ func (m *QueryGetProtoRevStatisticsByRouteResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryGetProtoRevStatisticsByRouteResponse proto.InternalMessageInfo
 
-func (m *QueryGetProtoRevStatisticsByRouteResponse) GetStatistics() *RouteStatistics {
+func (m *QueryGetProtoRevStatisticsByRouteResponse) GetStatistics() RouteStatistics {
 	if m != nil {
 		return m.Statistics
 	}
-	return nil
+	return RouteStatistics{}
 }
 
 // QueryGetProtoRevAllRouteStatisticsRequest is request type for the
@@ -524,7 +524,7 @@ var xxx_messageInfo_QueryGetProtoRevAllRouteStatisticsRequest proto.InternalMess
 type QueryGetProtoRevAllRouteStatisticsResponse struct {
 	// statistics contains the number of trades/profits the module has executed on
 	// all routes it has successfully executed a trade on
-	Statistics []RouteStatistics `protobuf:"bytes,1,rep,name=statistics,proto3" json:"statistics"`
+	Statistics []RouteStatistics `protobuf:"bytes,1,rep,name=statistics,proto3" json:"statistics" yaml:"statistics"`
 }
 
 func (m *QueryGetProtoRevAllRouteStatisticsResponse) Reset() {
@@ -618,7 +618,7 @@ var xxx_messageInfo_QueryGetProtoRevTokenPairArbRoutesRequest proto.InternalMess
 type QueryGetProtoRevTokenPairArbRoutesResponse struct {
 	// routes is a list of all of the hot routes that the module is currently
 	// arbitraging
-	Routes []*TokenPairArbRoutes `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty"`
+	Routes []TokenPairArbRoutes `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes" yaml:"routes"`
 }
 
 func (m *QueryGetProtoRevTokenPairArbRoutesResponse) Reset() {
@@ -658,7 +658,7 @@ func (m *QueryGetProtoRevTokenPairArbRoutesResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryGetProtoRevTokenPairArbRoutesResponse proto.InternalMessageInfo
 
-func (m *QueryGetProtoRevTokenPairArbRoutesResponse) GetRoutes() []*TokenPairArbRoutes {
+func (m *QueryGetProtoRevTokenPairArbRoutesResponse) GetRoutes() []TokenPairArbRoutes {
 	if m != nil {
 		return m.Routes
 	}
@@ -707,7 +707,7 @@ var xxx_messageInfo_QueryGetProtoRevAdminAccountRequest proto.InternalMessageInf
 // Query/GetProtoRevAdminAccount RPC method.
 type QueryGetProtoRevAdminAccountResponse struct {
 	// admin_account is the admin account of the module
-	AdminAccount string `protobuf:"bytes,1,opt,name=admin_account,json=adminAccount,proto3" json:"admin_account,omitempty"`
+	AdminAccount string `protobuf:"bytes,1,opt,name=admin_account,json=adminAccount,proto3" json:"admin_account,omitempty" yaml:"admin_account"`
 }
 
 func (m *QueryGetProtoRevAdminAccountResponse) Reset()         { *m = QueryGetProtoRevAdminAccountResponse{} }
@@ -794,7 +794,7 @@ var xxx_messageInfo_QueryGetProtoRevDeveloperAccountRequest proto.InternalMessag
 // Query/GetProtoRevDeveloperAccount RPC method.
 type QueryGetProtoRevDeveloperAccountResponse struct {
 	// developer_account is the developer account of the module
-	DeveloperAccount string `protobuf:"bytes,1,opt,name=developer_account,json=developerAccount,proto3" json:"developer_account,omitempty"`
+	DeveloperAccount string `protobuf:"bytes,1,opt,name=developer_account,json=developerAccount,proto3" json:"developer_account,omitempty" yaml:"developer_account"`
 }
 
 func (m *QueryGetProtoRevDeveloperAccountResponse) Reset() {
@@ -881,7 +881,7 @@ var xxx_messageInfo_QueryGetProtoRevPoolWeightsRequest proto.InternalMessageInfo
 // Query/GetProtoRevPoolWeights RPC method.
 type QueryGetProtoRevPoolWeightsResponse struct {
 	// pool_weights is a list of all of the pool weights
-	PoolWeights *PoolWeights `protobuf:"bytes,1,opt,name=pool_weights,json=poolWeights,proto3" json:"pool_weights,omitempty"`
+	PoolWeights PoolWeights `protobuf:"bytes,1,opt,name=pool_weights,json=poolWeights,proto3" json:"pool_weights" yaml:"pool_weights"`
 }
 
 func (m *QueryGetProtoRevPoolWeightsResponse) Reset()         { *m = QueryGetProtoRevPoolWeightsResponse{} }
@@ -917,11 +917,11 @@ func (m *QueryGetProtoRevPoolWeightsResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryGetProtoRevPoolWeightsResponse proto.InternalMessageInfo
 
-func (m *QueryGetProtoRevPoolWeightsResponse) GetPoolWeights() *PoolWeights {
+func (m *QueryGetProtoRevPoolWeightsResponse) GetPoolWeights() PoolWeights {
 	if m != nil {
 		return m.PoolWeights
 	}
-	return nil
+	return PoolWeights{}
 }
 
 // QueryGetProtoRevMaxPoolPointsPerBlockRequest is request type for the
@@ -971,7 +971,7 @@ var xxx_messageInfo_QueryGetProtoRevMaxPoolPointsPerBlockRequest proto.InternalM
 type QueryGetProtoRevMaxPoolPointsPerBlockResponse struct {
 	// max_pool_points_per_block is the maximum number of pool points that can be
 	// consumed per block
-	MaxPoolPointsPerBlock uint64 `protobuf:"varint,1,opt,name=max_pool_points_per_block,json=maxPoolPointsPerBlock,proto3" json:"max_pool_points_per_block,omitempty"`
+	MaxPoolPointsPerBlock uint64 `protobuf:"varint,1,opt,name=max_pool_points_per_block,json=maxPoolPointsPerBlock,proto3" json:"max_pool_points_per_block,omitempty" yaml:"max_pool_points_per_block"`
 }
 
 func (m *QueryGetProtoRevMaxPoolPointsPerBlockResponse) Reset() {
@@ -1065,7 +1065,7 @@ var xxx_messageInfo_QueryGetProtoRevMaxPoolPointsPerTxRequest proto.InternalMess
 type QueryGetProtoRevMaxPoolPointsPerTxResponse struct {
 	// max_pool_points_per_tx is the maximum number of pool points that can be
 	// consumed per transaction
-	MaxPoolPointsPerTx uint64 `protobuf:"varint,1,opt,name=max_pool_points_per_tx,json=maxPoolPointsPerTx,proto3" json:"max_pool_points_per_tx,omitempty"`
+	MaxPoolPointsPerTx uint64 `protobuf:"varint,1,opt,name=max_pool_points_per_tx,json=maxPoolPointsPerTx,proto3" json:"max_pool_points_per_tx,omitempty" yaml:"max_pool_points_per_tx"`
 }
 
 func (m *QueryGetProtoRevMaxPoolPointsPerTxResponse) Reset() {
@@ -1154,7 +1154,7 @@ var xxx_messageInfo_QueryGetProtoRevBaseDenomsRequest proto.InternalMessageInfo
 // Query/GetProtoRevBaseDenoms RPC method.
 type QueryGetProtoRevBaseDenomsResponse struct {
 	// base_denoms is a list of all of the base denoms and step sizes
-	BaseDenoms []*BaseDenom `protobuf:"bytes,1,rep,name=base_denoms,json=baseDenoms,proto3" json:"base_denoms,omitempty"`
+	BaseDenoms []BaseDenom `protobuf:"bytes,1,rep,name=base_denoms,json=baseDenoms,proto3" json:"base_denoms" yaml:"base_denoms"`
 }
 
 func (m *QueryGetProtoRevBaseDenomsResponse) Reset()         { *m = QueryGetProtoRevBaseDenomsResponse{} }
@@ -1190,7 +1190,7 @@ func (m *QueryGetProtoRevBaseDenomsResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryGetProtoRevBaseDenomsResponse proto.InternalMessageInfo
 
-func (m *QueryGetProtoRevBaseDenomsResponse) GetBaseDenoms() []*BaseDenom {
+func (m *QueryGetProtoRevBaseDenomsResponse) GetBaseDenoms() []BaseDenom {
 	if m != nil {
 		return m.BaseDenoms
 	}
@@ -1239,7 +1239,7 @@ var xxx_messageInfo_QueryGetProtoRevEnabledRequest proto.InternalMessageInfo
 // Query/GetProtoRevEnabled RPC method.
 type QueryGetProtoRevEnabledResponse struct {
 	// enabled is whether the module is enabled
-	Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+	Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty" yaml:"enabled"`
 }
 
 func (m *QueryGetProtoRevEnabledResponse) Reset()         { *m = QueryGetProtoRevEnabledResponse{} }
@@ -1318,88 +1318,97 @@ func init() {
 }
 
 var fileDescriptor_f5e7ac9973cce389 = []byte{
-	// 1293 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x58, 0x5d, 0x6f, 0xdb, 0x54,
-	0x18, 0xae, 0xd9, 0xd6, 0xc1, 0xe9, 0x40, 0xe3, 0xd0, 0x95, 0xd6, 0x74, 0x69, 0xe7, 0x34, 0x6d,
-	0xd3, 0x0f, 0x5b, 0x69, 0x8b, 0x18, 0x1a, 0x1d, 0x6b, 0x5a, 0x18, 0x13, 0x62, 0x0b, 0xa6, 0x68,
-	0x7c, 0x5c, 0x18, 0x3b, 0x39, 0xcd, 0x4c, 0x1d, 0x1f, 0xcf, 0x76, 0x42, 0x72, 0xc1, 0xcd, 0x6e,
-	0xb9, 0x41, 0xe2, 0x8f, 0xf0, 0x07, 0x90, 0xe0, 0x02, 0x69, 0x57, 0x68, 0x12, 0x42, 0x42, 0xbb,
-	0x28, 0x53, 0xcb, 0x25, 0x3f, 0x02, 0xf9, 0xf8, 0x75, 0xe2, 0xf8, 0x23, 0x89, 0xd3, 0xab, 0xf6,
-	0xf8, 0x3c, 0xef, 0xfb, 0x3e, 0xcf, 0x7b, 0xbe, 0x1e, 0x05, 0x2d, 0x51, 0xa7, 0x41, 0x1d, 0xdd,
-	0x91, 0x2c, 0x9b, 0xba, 0xd4, 0x26, 0x2d, 0xa9, 0x55, 0xd2, 0x88, 0xab, 0x96, 0xa4, 0xc7, 0x4d,
-	0x62, 0x77, 0x44, 0xf6, 0x19, 0xcf, 0x02, 0x4a, 0x0c, 0x50, 0x22, 0xa0, 0xf8, 0xe9, 0x3a, 0xad,
-	0x53, 0xf6, 0x55, 0xf2, 0xfe, 0xf3, 0x01, 0xfc, 0x7c, 0x9d, 0xd2, 0xba, 0x41, 0x24, 0xd5, 0xd2,
-	0x25, 0xd5, 0x34, 0xa9, 0xab, 0xba, 0x3a, 0x35, 0x21, 0x9c, 0x5f, 0xab, 0xb2, 0x74, 0x92, 0xa6,
-	0x3a, 0xc4, 0x2f, 0xd3, 0x2d, 0x6a, 0xa9, 0x75, 0xdd, 0x64, 0x60, 0xc0, 0x16, 0x52, 0xf9, 0x59,
-	0xaa, 0xad, 0x36, 0x82, 0x94, 0x2b, 0xe9, 0xb0, 0x80, 0xb1, 0x0f, 0xcc, 0x85, 0x6b, 0x07, 0x98,
-	0x2a, 0xd5, 0xa1, 0x9e, 0x30, 0x8d, 0xf0, 0xa7, 0x1e, 0xa3, 0x0a, 0xcb, 0x2e, 0x93, 0xc7, 0x4d,
-	0xe2, 0xb8, 0xc2, 0xe7, 0xe8, 0x8d, 0xbe, 0xaf, 0x8e, 0x45, 0x4d, 0x87, 0xe0, 0xdb, 0x68, 0xd2,
-	0x67, 0x31, 0xcb, 0x2d, 0x72, 0xab, 0x53, 0x5b, 0x8b, 0x62, 0x5a, 0x9f, 0x44, 0x3f, 0xb2, 0x7c,
-	0xf1, 0xe9, 0xc9, 0xc2, 0x84, 0x0c, 0x51, 0xc2, 0x0a, 0x2a, 0xb0, 0xb4, 0x77, 0x89, 0x5b, 0xf1,
-	0x02, 0x64, 0xd2, 0xba, 0xdf, 0x6c, 0x68, 0xc4, 0x7e, 0x70, 0x74, 0x68, 0xab, 0x35, 0xd2, 0xad,
-	0xff, 0x84, 0x43, 0xcb, 0xc3, 0x90, 0xc0, 0xe9, 0x0b, 0x74, 0xd5, 0x64, 0x33, 0x0a, 0x3d, 0x52,
-	0x5c, 0x36, 0xc7, 0xd8, 0xbd, 0x52, 0x16, 0xbd, 0xda, 0xcf, 0x4f, 0x16, 0x96, 0xeb, 0xba, 0xfb,
-	0xa8, 0xa9, 0x89, 0x55, 0xda, 0x90, 0xa0, 0x1b, 0xfe, 0x9f, 0x4d, 0xa7, 0x76, 0x2c, 0xb9, 0x1d,
-	0x8b, 0x38, 0xe2, 0x3d, 0xd3, 0x95, 0x5f, 0x33, 0xfb, 0x2a, 0x08, 0xbb, 0x71, 0xb6, 0x15, 0x9b,
-	0x1e, 0xe9, 0xae, 0x53, 0xee, 0x1c, 0x10, 0x93, 0x36, 0x80, 0x2d, 0x9e, 0x46, 0x97, 0x6a, 0xde,
-	0xd8, 0xaf, 0x2b, 0xfb, 0x03, 0xe1, 0xeb, 0xb8, 0x84, 0x68, 0x38, 0x48, 0x28, 0xa1, 0x49, 0x8b,
-	0xcd, 0x40, 0x5b, 0xe7, 0x44, 0x9f, 0x9f, 0xe8, 0x2d, 0x5a, 0xb7, 0xa3, 0xfb, 0x54, 0x37, 0x65,
-	0x00, 0x0a, 0x79, 0x74, 0x23, 0x9a, 0x7c, 0xcf, 0x30, 0x20, 0x7f, 0xd0, 0xc5, 0x2f, 0x91, 0x30,
-	0x08, 0x04, 0xd5, 0xb7, 0xd1, 0x65, 0x3f, 0xa9, 0xd7, 0xb7, 0x0b, 0x83, 0xcb, 0x07, 0x48, 0xe1,
-	0x0e, 0x5a, 0x8d, 0xa6, 0xfe, 0xcc, 0xdb, 0xf4, 0x8e, 0xab, 0x57, 0x9d, 0x72, 0x47, 0xa6, 0x4d,
-	0x97, 0x84, 0xda, 0x63, 0x7b, 0x63, 0x96, 0xfe, 0xa2, 0xec, 0x0f, 0x84, 0x16, 0x2a, 0x8e, 0x90,
-	0x01, 0x38, 0xde, 0x43, 0xc8, 0xe9, 0x4e, 0x42, 0x97, 0x8a, 0xe9, 0x9b, 0x8f, 0x05, 0xf7, 0xb2,
-	0xc9, 0xa1, 0x60, 0x61, 0x3d, 0x5e, 0x77, 0xcf, 0x30, 0xa2, 0x11, 0xd0, 0xc1, 0xef, 0xd1, 0xda,
-	0x28, 0x60, 0x60, 0xf9, 0x20, 0xc2, 0xf2, 0x42, 0x26, 0x96, 0x70, 0x56, 0x86, 0x70, 0x3d, 0xa4,
-	0xc7, 0xc4, 0xac, 0xa8, 0xba, 0xbd, 0x67, 0x6b, 0x2c, 0x41, 0x97, 0xab, 0x1d, 0xe7, 0x9a, 0x04,
-	0x06, 0xae, 0x07, 0x68, 0x92, 0xad, 0x43, 0xc0, 0x73, 0x23, 0x9d, 0x67, 0x42, 0x16, 0x88, 0x15,
-	0x0a, 0x28, 0x1f, 0xeb, 0x4f, 0xad, 0xa1, 0x9b, 0x7b, 0xd5, 0x2a, 0x6d, 0x9a, 0x6e, 0x40, 0xed,
-	0x63, 0xb4, 0x34, 0x18, 0x06, 0xa4, 0xf2, 0xe8, 0x55, 0xd5, 0xfb, 0xae, 0xa8, 0xfe, 0x04, 0x1c,
-	0xa8, 0x2b, 0x6a, 0x08, 0x2c, 0x14, 0xd1, 0x4a, 0x34, 0xd9, 0x01, 0x69, 0x11, 0x83, 0x5a, 0xc4,
-	0x8e, 0xd4, 0x7d, 0x18, 0xdf, 0xa5, 0x71, 0x28, 0xd4, 0x5e, 0x47, 0xaf, 0xd7, 0x82, 0xb9, 0x48,
-	0xfd, 0xab, 0xb5, 0x48, 0x90, 0xb0, 0x14, 0x3f, 0x59, 0x15, 0x4a, 0x8d, 0x87, 0x44, 0xaf, 0x3f,
-	0xea, 0x9d, 0x3f, 0x1a, 0xef, 0x4e, 0x1f, 0x0a, 0x2a, 0x7f, 0x84, 0xae, 0x58, 0x94, 0x1a, 0xca,
-	0x77, 0xfe, 0x77, 0xd8, 0xde, 0x85, 0x01, 0x77, 0x6b, 0x28, 0xc9, 0x94, 0xd5, 0x1b, 0x08, 0x22,
-	0xda, 0x88, 0x16, 0xfc, 0x44, 0x6d, 0x7b, 0xf0, 0x0a, 0xd5, 0x4d, 0xd7, 0xa9, 0x10, 0xbb, 0x6c,
-	0xd0, 0xea, 0x71, 0x40, 0x50, 0x47, 0x9b, 0x23, 0xe2, 0x81, 0xea, 0x4d, 0x34, 0xd7, 0x50, 0xdb,
-	0x0a, 0xa3, 0x6b, 0x31, 0x88, 0xe2, 0xb5, 0x4b, 0xf3, 0x40, 0x8c, 0xf7, 0x45, 0xf9, 0x5a, 0x23,
-	0x29, 0x43, 0xd2, 0x56, 0x8e, 0x96, 0x3a, 0x6c, 0x07, 0xbc, 0xbe, 0x89, 0x6f, 0xe5, 0x24, 0x30,
-	0x90, 0xda, 0x42, 0x33, 0x49, 0xa4, 0xdc, 0x36, 0x30, 0xc2, 0x8d, 0x58, 0x6c, 0xd2, 0xfd, 0x59,
-	0x56, 0x1d, 0xc2, 0xee, 0xe5, 0xee, 0xfa, 0x7d, 0x1b, 0x5f, 0xe5, 0x30, 0xa8, 0x7b, 0x92, 0xa6,
-	0xbc, 0x8b, 0x52, 0x61, 0xb7, 0x7e, 0x70, 0x9c, 0xf2, 0xe9, 0xab, 0xd7, 0x4d, 0x21, 0x23, 0xad,
-	0x9b, 0x4d, 0x58, 0x44, 0xb9, 0x68, 0xad, 0x0f, 0x4c, 0x55, 0x33, 0x48, 0x2d, 0x60, 0x73, 0x0b,
-	0x2d, 0xa4, 0x22, 0x80, 0xca, 0x2c, 0xba, 0x4c, 0xfc, 0x4f, 0x4c, 0xfa, 0xcb, 0x72, 0x30, 0xdc,
-	0xfa, 0x75, 0x06, 0x5d, 0x62, 0xd1, 0xf8, 0x07, 0x0e, 0x4d, 0xfa, 0x8f, 0x33, 0x1e, 0x70, 0xe6,
-	0xe3, 0x9e, 0x80, 0xdf, 0x1c, 0x11, 0xed, 0x73, 0x11, 0x96, 0x9e, 0xfc, 0xf9, 0xef, 0x4f, 0x2f,
-	0xe5, 0xf0, 0xbc, 0x14, 0x58, 0x95, 0x56, 0x69, 0xa7, 0x67, 0x57, 0x7c, 0x47, 0x80, 0xff, 0xe0,
-	0xd0, 0x5c, 0xea, 0x1b, 0x8f, 0xdf, 0x1f, 0x52, 0x72, 0x98, 0x8f, 0xe0, 0xef, 0x8c, 0x9f, 0x00,
-	0x64, 0x88, 0x4c, 0xc6, 0x2a, 0x5e, 0x4e, 0x96, 0x11, 0xb5, 0x1e, 0x51, 0x41, 0xfd, 0x2f, 0x7e,
-	0x16, 0x41, 0x89, 0x56, 0x23, 0x8b, 0xa0, 0x64, 0xb3, 0x31, 0x4c, 0x10, 0x3c, 0xf0, 0x8a, 0xd6,
-	0xf1, 0x37, 0x34, 0xfe, 0x85, 0x43, 0xd7, 0x12, 0x0d, 0x04, 0xbe, 0x35, 0x3a, 0x97, 0x98, 0x37,
-	0xe1, 0xdf, 0x1b, 0x2f, 0x18, 0x44, 0x14, 0x99, 0x88, 0x3c, 0xbe, 0x91, 0x2c, 0x42, 0x35, 0x0c,
-	0x05, 0x84, 0xe0, 0xe7, 0x1c, 0x9a, 0x1f, 0xe4, 0x31, 0x70, 0x79, 0x74, 0x26, 0x69, 0x16, 0x87,
-	0xdf, 0x3f, 0x57, 0x0e, 0x10, 0x55, 0x62, 0xa2, 0xd6, 0x71, 0x31, 0x59, 0x54, 0xcf, 0x17, 0x78,
-	0x8b, 0xc3, 0x1e, 0x60, 0x7c, 0xc2, 0xa1, 0xeb, 0x03, 0xbd, 0x09, 0xde, 0xcf, 0xd4, 0xe7, 0x64,
-	0x1b, 0xc4, 0x1f, 0x9c, 0x2f, 0x09, 0xe8, 0xdb, 0x62, 0xfa, 0x36, 0xf0, 0x5a, 0xfa, 0xa2, 0x31,
-	0x55, 0x4a, 0x4f, 0x29, 0xfe, 0xa7, 0x5f, 0x60, 0xdc, 0x8a, 0x64, 0x11, 0x98, 0xea, 0x9d, 0xb2,
-	0x08, 0x4c, 0xf7, 0x54, 0xc2, 0x36, 0x13, 0xb8, 0x89, 0xd7, 0x93, 0x05, 0xba, 0x5e, 0xa4, 0x62,
-	0xa9, 0xba, 0xad, 0xa8, 0xb6, 0xe6, 0x6b, 0x75, 0xf0, 0xef, 0x1c, 0x7a, 0x33, 0xc5, 0x17, 0xe1,
-	0xdd, 0x0c, 0x7d, 0x8f, 0xdb, 0x2e, 0xfe, 0xf6, 0xb8, 0xe1, 0xa0, 0x67, 0x9d, 0xe9, 0x29, 0xe0,
-	0x7c, 0xca, 0x82, 0x85, 0xad, 0x1a, 0xfe, 0x8b, 0x43, 0x6f, 0x0d, 0xf0, 0x59, 0x78, 0x6f, 0x74,
-	0x32, 0x29, 0x76, 0x8e, 0x2f, 0x9f, 0x27, 0x05, 0x68, 0x92, 0x98, 0xa6, 0x22, 0x5e, 0x49, 0xd6,
-	0x14, 0xb3, 0x80, 0xf8, 0x37, 0x0e, 0xcd, 0x24, 0x1b, 0x38, 0x9c, 0xe1, 0x0e, 0x8b, 0xbb, 0x43,
-	0x7e, 0x77, 0xcc, 0x68, 0x10, 0xb2, 0xc6, 0x84, 0x2c, 0x61, 0x21, 0xe5, 0x1e, 0x0f, 0x39, 0x4a,
-	0xfc, 0xa2, 0xff, 0x14, 0xc5, 0xbd, 0x54, 0x96, 0x53, 0x94, 0x6a, 0xdb, 0xb2, 0x9c, 0xa2, 0x74,
-	0x3b, 0x27, 0xec, 0x30, 0x61, 0x22, 0xde, 0x48, 0x16, 0x96, 0x6c, 0xf5, 0xf0, 0x7f, 0x1c, 0x5a,
-	0x1c, 0x66, 0x63, 0xf1, 0x87, 0xe3, 0x13, 0x0c, 0xfb, 0x66, 0xfe, 0xee, 0xb9, 0xf3, 0x80, 0xd6,
-	0x77, 0x98, 0xd6, 0x12, 0x96, 0x46, 0xd7, 0xca, 0xbc, 0x76, 0xf4, 0x55, 0xee, 0xd9, 0xd2, 0x2c,
-	0xaf, 0x72, 0xcc, 0xf1, 0x66, 0x79, 0x95, 0xe3, 0x4e, 0x78, 0xd8, 0xab, 0x1c, 0x72, 0xc9, 0xf8,
-	0x67, 0x0e, 0xe1, 0xb8, 0x91, 0xc5, 0x37, 0x47, 0xaf, 0xdf, 0xef, 0x8e, 0xf9, 0x77, 0xc7, 0x88,
-	0x04, 0xda, 0x05, 0x46, 0x7b, 0x01, 0x5f, 0x4f, 0xa6, 0x0d, 0x16, 0xba, 0x7c, 0xff, 0xe9, 0x69,
-	0x8e, 0x7b, 0x76, 0x9a, 0xe3, 0x5e, 0x9c, 0xe6, 0xb8, 0x1f, 0xcf, 0x72, 0x13, 0xcf, 0xce, 0x72,
-	0x13, 0x7f, 0x9f, 0xe5, 0x26, 0xbe, 0xda, 0x09, 0xfd, 0xc0, 0x04, 0x29, 0x36, 0x0d, 0x55, 0x73,
-	0x42, 0xf9, 0xde, 0x96, 0xda, 0xa1, 0x87, 0xa0, 0x63, 0x11, 0x47, 0x9b, 0x64, 0xe3, 0xed, 0xff,
-	0x03, 0x00, 0x00, 0xff, 0xff, 0xdf, 0xeb, 0x49, 0x05, 0x92, 0x14, 0x00, 0x00,
+	// 1427 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5b, 0x6f, 0xdc, 0x44,
+	0x18, 0x8d, 0x69, 0x9b, 0xc2, 0xf4, 0xa2, 0x76, 0xda, 0xa6, 0x89, 0x9b, 0xee, 0xa6, 0x93, 0xdd,
+	0xa4, 0x9b, 0x8b, 0xad, 0xb4, 0x45, 0x5c, 0x0b, 0xc4, 0x0d, 0x54, 0x15, 0xa2, 0x59, 0x4c, 0x11,
+	0x12, 0x48, 0x18, 0x7b, 0x77, 0xb2, 0xb5, 0xe2, 0xf5, 0x38, 0xb6, 0x37, 0xec, 0xbe, 0x82, 0x84,
+	0x84, 0x40, 0xe2, 0xf6, 0xcc, 0x7f, 0xe0, 0x0f, 0x20, 0xc1, 0x03, 0x52, 0x9f, 0x50, 0x25, 0x84,
+	0x84, 0xfa, 0xb0, 0x54, 0x09, 0x8f, 0x3c, 0xed, 0x2f, 0x40, 0x9e, 0x19, 0xef, 0x7a, 0x7d, 0xd9,
+	0x5b, 0x24, 0x9e, 0xb2, 0x9e, 0x39, 0x73, 0xbe, 0x73, 0xe6, 0x7a, 0x14, 0x50, 0x20, 0x5e, 0x9d,
+	0x78, 0xa6, 0x27, 0x3b, 0x2e, 0xf1, 0x89, 0x8b, 0xf7, 0xe5, 0xfd, 0x0d, 0x03, 0xfb, 0xfa, 0x86,
+	0xbc, 0xd7, 0xc0, 0x6e, 0x4b, 0xa2, 0xcd, 0x70, 0x96, 0xa3, 0xa4, 0x10, 0x25, 0x71, 0x94, 0x78,
+	0xb1, 0x46, 0x6a, 0x84, 0xb6, 0xca, 0xc1, 0x2f, 0x06, 0x10, 0xe7, 0x6b, 0x84, 0xd4, 0x2c, 0x2c,
+	0xeb, 0x8e, 0x29, 0xeb, 0xb6, 0x4d, 0x7c, 0xdd, 0x37, 0x89, 0xcd, 0x87, 0x8b, 0x2b, 0x15, 0x4a,
+	0x27, 0x1b, 0xba, 0x87, 0x59, 0x99, 0x6e, 0x51, 0x47, 0xaf, 0x99, 0x36, 0x05, 0x73, 0x6c, 0x31,
+	0x53, 0x9f, 0xa3, 0xbb, 0x7a, 0x3d, 0xa4, 0x5c, 0xce, 0x86, 0x85, 0x8a, 0x19, 0x30, 0x17, 0xad,
+	0x1d, 0x62, 0x2a, 0xc4, 0xe4, 0xf5, 0xd0, 0x45, 0x00, 0xdf, 0x0d, 0x14, 0x95, 0x29, 0xbb, 0x8a,
+	0xf7, 0x1a, 0xd8, 0xf3, 0xd1, 0x0e, 0xb8, 0xd0, 0xd7, 0xea, 0x39, 0xc4, 0xf6, 0x30, 0xdc, 0x06,
+	0xd3, 0x4c, 0xc5, 0xac, 0xb0, 0x20, 0x5c, 0x3f, 0x75, 0x63, 0x41, 0xca, 0x9a, 0x27, 0x89, 0x8d,
+	0x54, 0x2e, 0x3d, 0x6a, 0xe7, 0xa7, 0x3a, 0xed, 0xfc, 0x99, 0x96, 0x5e, 0xb7, 0x5e, 0x46, 0x6c,
+	0x34, 0x52, 0x39, 0x0d, 0x5a, 0x06, 0x45, 0x5a, 0xe7, 0x2e, 0xf6, 0xcb, 0x01, 0x83, 0x8a, 0xf7,
+	0xef, 0x37, 0xea, 0x06, 0x76, 0xb7, 0x77, 0x1e, 0xb8, 0x7a, 0x15, 0x77, 0x05, 0xfd, 0x28, 0x80,
+	0xa5, 0x61, 0x48, 0x2e, 0xd2, 0x03, 0xe7, 0x6c, 0xda, 0xa3, 0x91, 0x1d, 0xcd, 0xa7, 0x7d, 0x54,
+	0xee, 0x73, 0xca, 0xbd, 0x40, 0xcc, 0x93, 0x76, 0x7e, 0xa9, 0x66, 0xfa, 0x0f, 0x1b, 0x86, 0x54,
+	0x21, 0x75, 0x99, 0x4f, 0x0f, 0xfb, 0xb3, 0xee, 0x55, 0x77, 0x65, 0xbf, 0xe5, 0x60, 0x4f, 0xba,
+	0x67, 0xfb, 0x9d, 0x76, 0xfe, 0x32, 0x93, 0x1d, 0xe7, 0x43, 0xea, 0x59, 0xbb, 0xaf, 0x38, 0xda,
+	0x4e, 0x1a, 0x29, 0xbb, 0x64, 0xc7, 0xf4, 0x3d, 0xa5, 0xb5, 0x85, 0x6d, 0x52, 0xe7, 0x46, 0xe0,
+	0x12, 0x38, 0x51, 0x0d, 0xbe, 0xb9, 0xa4, 0x73, 0x9d, 0x76, 0xfe, 0x34, 0x2b, 0x42, 0x9b, 0x91,
+	0xca, 0xba, 0x91, 0x9d, 0xf4, 0x1b, 0x27, 0xe4, 0x7e, 0xb7, 0xc0, 0xb4, 0x43, 0x7b, 0xf8, 0xa2,
+	0xcc, 0x49, 0xcc, 0x8c, 0x14, 0x2c, 0x79, 0x77, 0x3d, 0xee, 0x10, 0xd3, 0x56, 0xce, 0x47, 0x56,
+	0x82, 0x0e, 0x09, 0x56, 0x82, 0xfd, 0x58, 0x04, 0xd7, 0xe2, 0xf5, 0x36, 0x2d, 0x8b, 0x97, 0x0c,
+	0x57, 0x61, 0x0f, 0xa0, 0x41, 0x20, 0x2e, 0xe8, 0x6d, 0x70, 0x92, 0x91, 0x06, 0xf3, 0x7e, 0x6c,
+	0xb0, 0xa2, 0x19, 0xbe, 0x3f, 0xce, 0x46, 0x55, 0x79, 0x48, 0x3d, 0xd9, 0xfd, 0x05, 0xae, 0xc7,
+	0x4b, 0xbe, 0x17, 0x9c, 0x2e, 0xcf, 0x37, 0x2b, 0x9e, 0xd2, 0x52, 0x49, 0xc3, 0xc7, 0x91, 0xb9,
+	0x75, 0x83, 0x6f, 0x5a, 0xf6, 0x78, 0x74, 0x6e, 0x69, 0x33, 0x52, 0x59, 0x37, 0xfa, 0x4e, 0x00,
+	0xa5, 0x11, 0x48, 0xb9, 0x9d, 0x2a, 0x00, 0x5e, 0xb7, 0x93, 0xcf, 0x71, 0x29, 0x7b, 0xe3, 0xd3,
+	0xc1, 0x11, 0xb6, 0x39, 0xee, 0xf0, 0x3c, 0x53, 0xd2, 0xa3, 0x42, 0x6a, 0x84, 0x17, 0xad, 0x26,
+	0x25, 0x6d, 0x5a, 0x56, 0x8c, 0x2c, 0x5c, 0x87, 0xef, 0x05, 0xb0, 0x32, 0x0a, 0x3a, 0xc3, 0xc1,
+	0xb1, 0xff, 0xcb, 0xc1, 0x03, 0xb2, 0x8b, 0xed, 0xb2, 0x6e, 0xba, 0x9b, 0xae, 0x41, 0x59, 0xbb,
+	0x0e, 0xbe, 0x4c, 0x71, 0x90, 0x86, 0xe6, 0x0e, 0x3e, 0x02, 0xd3, 0x74, 0xe9, 0x42, 0xf5, 0x6b,
+	0xd9, 0xea, 0x93, 0x2c, 0xf1, 0x4b, 0x88, 0x31, 0x21, 0x95, 0x53, 0xa2, 0x22, 0x58, 0x4c, 0x4c,
+	0x66, 0xb5, 0x6e, 0xda, 0x9b, 0x95, 0x0a, 0x69, 0xd8, 0x7e, 0x28, 0x19, 0x83, 0xc2, 0x60, 0x18,
+	0xd7, 0x7a, 0x1b, 0x9c, 0xd1, 0x83, 0x76, 0x4d, 0x67, 0x1d, 0xfc, 0xa4, 0xcf, 0x76, 0xda, 0xf9,
+	0x8b, 0x4c, 0x40, 0x5f, 0x37, 0x52, 0x4f, 0xeb, 0x11, 0x1a, 0x54, 0x02, 0xcb, 0xf1, 0x32, 0x5b,
+	0x78, 0x1f, 0x5b, 0xc4, 0xc1, 0x6e, 0x4c, 0x51, 0x23, 0x79, 0x36, 0x92, 0x50, 0xae, 0xea, 0x1e,
+	0x38, 0x5f, 0x0d, 0xfb, 0x62, 0xca, 0xe6, 0x3b, 0xed, 0xfc, 0x6c, 0x78, 0x07, 0xc5, 0x20, 0x48,
+	0x3d, 0x57, 0x8d, 0x51, 0xa2, 0x42, 0xf2, 0x16, 0x28, 0x13, 0x62, 0x7d, 0x80, 0xcd, 0xda, 0xc3,
+	0xde, 0x5d, 0xf1, 0xb5, 0x90, 0x9c, 0xd6, 0x3e, 0x18, 0x17, 0x86, 0xc1, 0x69, 0x87, 0x10, 0x4b,
+	0xfb, 0x94, 0xb5, 0xf3, 0x03, 0x56, 0x1c, 0xf0, 0xb2, 0xf4, 0x48, 0x94, 0x2b, 0x7c, 0x65, 0x2f,
+	0xf0, 0xeb, 0x23, 0x42, 0x84, 0xd4, 0x53, 0x4e, 0x0f, 0x89, 0x24, 0xb0, 0x16, 0x57, 0xf3, 0x8e,
+	0xde, 0x0c, 0xb8, 0xca, 0xc4, 0xb4, 0x7d, 0xaf, 0x8c, 0x5d, 0xc5, 0x22, 0x95, 0xdd, 0x50, 0xfe,
+	0x37, 0x02, 0x58, 0x1f, 0x71, 0x00, 0x37, 0xf2, 0x31, 0x98, 0xab, 0xeb, 0x4d, 0x8d, 0x6a, 0x70,
+	0x28, 0x44, 0x0b, 0x26, 0xd2, 0x08, 0x40, 0xd4, 0xd5, 0x71, 0xa5, 0xd0, 0x69, 0xe7, 0x17, 0x98,
+	0xd4, 0x4c, 0x28, 0x52, 0x2f, 0xd5, 0xd3, 0xea, 0xa4, 0x9d, 0xaf, 0xb8, 0xa0, 0x07, 0xcd, 0x50,
+	0xfe, 0xe7, 0x29, 0xe7, 0x2b, 0x0d, 0xcd, 0xb5, 0xbf, 0x0f, 0x66, 0xd2, 0x04, 0xf9, 0x4d, 0x2e,
+	0xfc, 0x5a, 0xa7, 0x9d, 0xbf, 0x9a, 0x2d, 0xdc, 0x6f, 0x22, 0x15, 0xd6, 0x13, 0xf4, 0x69, 0x8f,
+	0x8a, 0xa2, 0x7b, 0x98, 0xbe, 0x5f, 0xdd, 0x8d, 0xf2, 0x85, 0x90, 0xdc, 0x4f, 0x51, 0x14, 0x97,
+	0xf8, 0x09, 0x38, 0x15, 0x3c, 0x1f, 0x1a, 0x7d, 0x1e, 0xc3, 0x7b, 0x60, 0x31, 0x7b, 0x9b, 0x74,
+	0x29, 0x14, 0x91, 0x6f, 0x12, 0xc8, 0x0c, 0x44, 0x58, 0x90, 0x0a, 0x8c, 0x6e, 0x25, 0xb4, 0x00,
+	0x72, 0x71, 0x1d, 0x6f, 0xda, 0xba, 0x61, 0xe1, 0x6a, 0x28, 0x75, 0x1b, 0xe4, 0x33, 0x11, 0x5c,
+	0xe6, 0x1a, 0x38, 0x89, 0x59, 0x13, 0x9d, 0xba, 0x67, 0x15, 0xd8, 0x7b, 0xdd, 0x78, 0x07, 0x52,
+	0x43, 0xc8, 0x8d, 0x5f, 0x66, 0xc0, 0x09, 0xca, 0x08, 0xbf, 0x12, 0xc0, 0x34, 0xcb, 0x4c, 0x70,
+	0xc0, 0xe5, 0x96, 0x8c, 0x6a, 0xe2, 0xfa, 0x88, 0x68, 0xa6, 0x0f, 0x15, 0x3e, 0xfb, 0xe3, 0x9f,
+	0x1f, 0x9e, 0xc9, 0xc1, 0x79, 0x39, 0x4c, 0x90, 0xfb, 0x1b, 0xb7, 0x7a, 0x29, 0x92, 0xe5, 0x32,
+	0xf8, 0xbb, 0x00, 0xe6, 0x32, 0x93, 0x16, 0x7c, 0x7d, 0x48, 0xc9, 0x61, 0x69, 0x4e, 0x7c, 0x63,
+	0x72, 0x02, 0x6e, 0x43, 0xa2, 0x36, 0xae, 0xc3, 0xa5, 0x74, 0x1b, 0xf1, 0xc0, 0x16, 0x37, 0xd4,
+	0x1f, 0xa5, 0xc6, 0x31, 0x94, 0x9a, 0xea, 0xc6, 0x31, 0x94, 0x9e, 0xe2, 0x86, 0x19, 0xe2, 0x71,
+	0x48, 0x33, 0x5a, 0x6c, 0xeb, 0xc2, 0x9f, 0x05, 0x70, 0x29, 0x35, 0x86, 0xc1, 0x57, 0x46, 0xd7,
+	0x92, 0x48, 0x78, 0xe2, 0xab, 0x93, 0x0d, 0xe6, 0x26, 0x4a, 0xd4, 0xc4, 0x22, 0xbc, 0x96, 0x6e,
+	0x42, 0xb7, 0x2c, 0x8d, 0x1b, 0x81, 0x4f, 0x04, 0x30, 0x3f, 0x28, 0x7e, 0x41, 0x65, 0x74, 0x25,
+	0x59, 0x81, 0x50, 0xbc, 0x73, 0x24, 0x0e, 0x6e, 0x6a, 0x83, 0x9a, 0x5a, 0x85, 0xa5, 0x74, 0x53,
+	0xbd, 0x04, 0x14, 0x2c, 0x0e, 0x8d, 0x14, 0xb0, 0x2d, 0x80, 0xab, 0x03, 0xa3, 0x19, 0xbc, 0x33,
+	0xd6, 0x3c, 0xa7, 0xc7, 0x40, 0x71, 0xeb, 0x68, 0x24, 0xdc, 0xdf, 0x0d, 0xea, 0x6f, 0x0d, 0xae,
+	0x64, 0x2f, 0x1a, 0x75, 0xa5, 0xf5, 0x9c, 0xc2, 0xbf, 0xfb, 0x0d, 0x26, 0x33, 0xd7, 0x38, 0x06,
+	0x33, 0x53, 0xe2, 0x38, 0x06, 0xb3, 0xc3, 0x23, 0xba, 0x49, 0x0d, 0xae, 0xc3, 0xd5, 0x74, 0x83,
+	0x7e, 0x30, 0x52, 0x73, 0x74, 0xd3, 0xd5, 0x74, 0xd7, 0x60, 0x5e, 0x3d, 0xf8, 0x9b, 0x00, 0x2e,
+	0x67, 0x24, 0x3d, 0x78, 0x7b, 0x8c, 0x79, 0x4f, 0x06, 0x49, 0xf1, 0xb5, 0x49, 0x87, 0x73, 0x3f,
+	0xab, 0xd4, 0x4f, 0x11, 0x2e, 0x66, 0x2c, 0x58, 0x34, 0x5d, 0xc2, 0x3f, 0x05, 0x70, 0x65, 0x40,
+	0x3e, 0x84, 0x9b, 0xa3, 0x8b, 0xc9, 0x88, 0xa1, 0xa2, 0x72, 0x14, 0x0a, 0xee, 0x49, 0xa6, 0x9e,
+	0x4a, 0x70, 0x39, 0xdd, 0x53, 0x22, 0x97, 0xc2, 0x5f, 0x05, 0x30, 0x93, 0x9e, 0x2c, 0xe1, 0x18,
+	0x77, 0x58, 0x32, 0xb7, 0x8a, 0xb7, 0x27, 0x1c, 0xcd, 0x8d, 0xac, 0x50, 0x23, 0x05, 0x88, 0x32,
+	0xee, 0xf1, 0x48, 0x42, 0x85, 0x4f, 0xfb, 0x4f, 0x51, 0x32, 0x9f, 0x8d, 0x73, 0x8a, 0x32, 0xb3,
+	0xe0, 0x38, 0xa7, 0x28, 0x3b, 0x22, 0xa2, 0x5b, 0xd4, 0x98, 0x04, 0xd7, 0xd2, 0x8d, 0xa5, 0xc7,
+	0x42, 0xf8, 0xaf, 0x00, 0x16, 0x86, 0x25, 0x68, 0xf8, 0xd6, 0xe4, 0x02, 0xa3, 0x99, 0x5d, 0xbc,
+	0x7b, 0x64, 0x1e, 0xee, 0xf5, 0x05, 0xea, 0x75, 0x03, 0xca, 0xa3, 0x7b, 0xa5, 0xd9, 0x3d, 0xfe,
+	0x2a, 0xf7, 0x62, 0xec, 0x38, 0xaf, 0x72, 0x22, 0x22, 0x8f, 0xf3, 0x2a, 0x27, 0x93, 0xf3, 0xb0,
+	0x57, 0x39, 0x92, 0x87, 0xe1, 0x4f, 0x02, 0x80, 0xc9, 0x70, 0x0b, 0x5f, 0x1c, 0xbd, 0x7e, 0x7f,
+	0x62, 0x16, 0x5f, 0x9a, 0x60, 0x24, 0x97, 0x5d, 0xa4, 0xb2, 0xf3, 0xf0, 0x6a, 0xba, 0x6c, 0x1e,
+	0xa1, 0x95, 0xfb, 0x8f, 0x0e, 0x72, 0xc2, 0xe3, 0x83, 0x9c, 0xf0, 0xf4, 0x20, 0x27, 0x7c, 0x7b,
+	0x98, 0x9b, 0x7a, 0x7c, 0x98, 0x9b, 0xfa, 0xeb, 0x30, 0x37, 0xf5, 0xe1, 0xad, 0xc8, 0xbf, 0xf9,
+	0x38, 0xc5, 0xba, 0xa5, 0x1b, 0x5e, 0x84, 0xef, 0x79, 0xb9, 0x19, 0x79, 0x08, 0x5a, 0x0e, 0xf6,
+	0x8c, 0x69, 0xfa, 0x7d, 0xf3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x19, 0xc0, 0x09, 0x29,
+	0x16, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -2294,18 +2303,16 @@ func (m *QueryGetProtoRevStatisticsByRouteResponse) MarshalToSizedBuffer(dAtA []
 	_ = i
 	var l int
 	_ = l
-	if m.Statistics != nil {
-		{
-			size, err := m.Statistics.MarshalToSizedBuffer(dAtA[:i])
-			if err != nil {
-				return 0, err
-			}
-			i -= size
-			i = encodeVarintQuery(dAtA, i, uint64(size))
+	{
+		size, err := m.Statistics.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
 		}
-		i--
-		dAtA[i] = 0xa
+		i -= size
+		i = encodeVarintQuery(dAtA, i, uint64(size))
 	}
+	i--
+	dAtA[i] = 0xa
 	return len(dAtA) - i, nil
 }
 
@@ -2578,18 +2585,16 @@ func (m *QueryGetProtoRevPoolWeightsResponse) MarshalToSizedBuffer(dAtA []byte)
 	_ = i
 	var l int
 	_ = l
-	if m.PoolWeights != nil {
-		{
-			size, err := m.PoolWeights.MarshalToSizedBuffer(dAtA[:i])
-			if err != nil {
-				return 0, err
-			}
-			i -= size
-			i = encodeVarintQuery(dAtA, i, uint64(size))
+	{
+		size, err := m.PoolWeights.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
 		}
-		i--
-		dAtA[i] = 0xa
+		i -= size
+		i = encodeVarintQuery(dAtA, i, uint64(size))
 	}
+	i--
+	dAtA[i] = 0xa
 	return len(dAtA) - i, nil
 }
 
@@ -2934,10 +2939,8 @@ func (m *QueryGetProtoRevStatisticsByRouteResponse) Size() (n int) {
 	}
 	var l int
 	_ = l
-	if m.Statistics != nil {
-		l = m.Statistics.Size()
-		n += 1 + l + sovQuery(uint64(l))
-	}
+	l = m.Statistics.Size()
+	n += 1 + l + sovQuery(uint64(l))
 	return n
 }
 
@@ -3048,10 +3051,8 @@ func (m *QueryGetProtoRevPoolWeightsResponse) Size() (n int) {
 	}
 	var l int
 	_ = l
-	if m.PoolWeights != nil {
-		l = m.PoolWeights.Size()
-		n += 1 + l + sovQuery(uint64(l))
-	}
+	l = m.PoolWeights.Size()
+	n += 1 + l + sovQuery(uint64(l))
 	return n
 }
 
@@ -3691,7 +3692,7 @@ func (m *QueryGetProtoRevAllProfitsResponse) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Profits = append(m.Profits, &types.Coin{})
+			m.Profits = append(m.Profits, types.Coin{})
 			if err := m.Profits[len(m.Profits)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -3901,9 +3902,6 @@ func (m *QueryGetProtoRevStatisticsByRouteResponse) Unmarshal(dAtA []byte) error
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			if m.Statistics == nil {
-				m.Statistics = &RouteStatistics{}
-			}
 			if err := m.Statistics.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -4171,7 +4169,7 @@ func (m *QueryGetProtoRevTokenPairArbRoutesResponse) Unmarshal(dAtA []byte) erro
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.Routes = append(m.Routes, &TokenPairArbRoutes{})
+			m.Routes = append(m.Routes, TokenPairArbRoutes{})
 			if err := m.Routes[len(m.Routes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -4569,9 +4567,6 @@ func (m *QueryGetProtoRevPoolWeightsResponse) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			if m.PoolWeights == nil {
-				m.PoolWeights = &PoolWeights{}
-			}
 			if err := m.PoolWeights.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -4943,7 +4938,7 @@ func (m *QueryGetProtoRevBaseDenomsResponse) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.BaseDenoms = append(m.BaseDenoms, &BaseDenom{})
+			m.BaseDenoms = append(m.BaseDenoms, BaseDenom{})
 			if err := m.BaseDenoms[len(m.BaseDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
diff --git a/x/protorev/types/token_pair_arb_routes.go b/x/protorev/types/token_pair_arb_routes.go
index 44cfae3f8..d3e86e450 100644
--- a/x/protorev/types/token_pair_arb_routes.go
+++ b/x/protorev/types/token_pair_arb_routes.go
@@ -7,7 +7,7 @@ import (
 )
 
 // Creates a new TokenPairArbRoutes object
-func NewTokenPairArbRoutes(routes []*Route, tokenA, tokenB string) TokenPairArbRoutes {
+func NewTokenPairArbRoutes(routes []Route, tokenA, tokenB string) TokenPairArbRoutes {
 	return TokenPairArbRoutes{
 		ArbRoutes: routes,
 		TokenIn:   tokenA,
@@ -15,6 +15,28 @@ func NewTokenPairArbRoutes(routes []*Route, tokenA, tokenB string) TokenPairArbR
 	}
 }
 
+func ValidateTokenPairArbRoutes(tokenPairArbRoutes []TokenPairArbRoutes) error {
+	if tokenPairArbRoutes == nil {
+		return fmt.Errorf("token pair arb routes cannot be nil")
+	}
+
+	seenPairs := make(map[string]bool)
+	for _, tokenPairArbRoute := range tokenPairArbRoutes {
+		if err := tokenPairArbRoute.Validate(); err != nil {
+			return err
+		}
+
+		// Ensure that the token pair is unique
+		pair := tokenPairArbRoute.TokenIn + "/" + tokenPairArbRoute.TokenOut
+		if seenPairs[pair] {
+			return fmt.Errorf("duplicate token pair %s", pair)
+		}
+		seenPairs[pair] = true
+	}
+
+	return nil
+}
+
 func (tp *TokenPairArbRoutes) Validate() error {
 	if tp == nil {
 		return fmt.Errorf("token pair cannot be nil")
@@ -25,18 +47,13 @@ func (tp *TokenPairArbRoutes) Validate() error {
 		return fmt.Errorf("token names cannot be empty")
 	}
 
-	// The list cannot be nil
-	if tp.ArbRoutes == nil {
-		return fmt.Errorf("the list of routes cannot be nil")
+	if tp.ArbRoutes == nil || len(tp.ArbRoutes) == 0 {
+		return fmt.Errorf("there must be at least one route")
 	}
 
 	// Iterate through all of the possible routes for this pool
 	for _, route := range tp.ArbRoutes {
-		if route == nil {
-			return fmt.Errorf("route cannot be nil")
-		}
-
-		if route.StepSize == nil || route.StepSize.LT(sdk.OneInt()) {
+		if route.StepSize.IsNil() || route.StepSize.LT(sdk.OneInt()) {
 			return fmt.Errorf("step size must be greater than 0")
 		}
 
@@ -56,9 +73,9 @@ func (tp *TokenPairArbRoutes) Validate() error {
 
 // isValidRoute checks that the route has more than 1 trade, that the first and last trades have matching denoms,
 // and that the denoms match across hops
-func isValidRoute(route *Route) error {
+func isValidRoute(route Route) error {
 	// support routes of varying length (with the exception of length 1)
-	if route.Trades == nil || len(route.Trades) <= 1 {
+	if len(route.Trades) <= 1 {
 		return fmt.Errorf("there must be at least two trades (hops) per route")
 	}
 
@@ -70,10 +87,6 @@ func isValidRoute(route *Route) error {
 	// Iterate through all of the trades in the route
 	prevDenom := route.Trades[0].TokenOut
 	for _, trade := range route.Trades[1:] {
-		if trade == nil {
-			return fmt.Errorf("trade cannot be nil")
-		}
-
 		// Validate that the denoms match
 		if prevDenom != trade.TokenIn {
 			return fmt.Errorf("the denoms must match across hops")
@@ -87,7 +100,7 @@ func isValidRoute(route *Route) error {
 }
 
 // hasPlaceholderPool checks that the route has a placeholder pool id (id of 0) for the token pair that we are arbitraging
-func hasPlaceholderPool(swapInDenom, swapOutDenom string, trades []*Trade) error {
+func hasPlaceholderPool(swapInDenom, swapOutDenom string, trades []Trade) error {
 	foundPair := false
 	foundPlaceholder := false
 	for _, trade := range trades {
@@ -112,7 +125,7 @@ func hasPlaceholderPool(swapInDenom, swapOutDenom string, trades []*Trade) error
 	return nil
 }
 
-func NewRoutes(trades []*Trade) Route {
+func NewRoutes(trades []Trade) Route {
 	return Route{
 		Trades: trades,
 	}
diff --git a/x/protorev/types/tx.pb.go b/x/protorev/types/tx.pb.go
index ea158f93d..5e25551ea 100644
--- a/x/protorev/types/tx.pb.go
+++ b/x/protorev/types/tx.pb.go
@@ -6,6 +6,7 @@ package types
 import (
 	context "context"
 	fmt "fmt"
+	_ "github.com/cosmos/cosmos-proto"
 	_ "github.com/gogo/protobuf/gogoproto"
 	grpc1 "github.com/gogo/protobuf/grpc"
 	proto "github.com/gogo/protobuf/proto"
@@ -32,9 +33,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 // MsgSetHotRoutes defines the Msg/SetHotRoutes request type.
 type MsgSetHotRoutes struct {
 	// admin is the account that is authorized to set the hot routes.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// hot_routes is the list of hot routes to set.
-	HotRoutes []*TokenPairArbRoutes `protobuf:"bytes,2,rep,name=hot_routes,json=hotRoutes,proto3" json:"hot_routes,omitempty"`
+	HotRoutes []TokenPairArbRoutes `protobuf:"bytes,2,rep,name=hot_routes,json=hotRoutes,proto3" json:"hot_routes" yaml:"hot_routes"`
 }
 
 func (m *MsgSetHotRoutes) Reset()         { *m = MsgSetHotRoutes{} }
@@ -77,7 +78,7 @@ func (m *MsgSetHotRoutes) GetAdmin() string {
 	return ""
 }
 
-func (m *MsgSetHotRoutes) GetHotRoutes() []*TokenPairArbRoutes {
+func (m *MsgSetHotRoutes) GetHotRoutes() []TokenPairArbRoutes {
 	if m != nil {
 		return m.HotRoutes
 	}
@@ -124,10 +125,10 @@ var xxx_messageInfo_MsgSetHotRoutesResponse proto.InternalMessageInfo
 // MsgSetDeveloperAccount defines the Msg/SetDeveloperAccount request type.
 type MsgSetDeveloperAccount struct {
 	// admin is the account that is authorized to set the developer account.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// developer_account is the account that will receive a portion of the profits
 	// from the protorev module.
-	DeveloperAccount string `protobuf:"bytes,2,opt,name=developer_account,json=developerAccount,proto3" json:"developer_account,omitempty"`
+	DeveloperAccount string `protobuf:"bytes,2,opt,name=developer_account,json=developerAccount,proto3" json:"developer_account,omitempty" yaml:"developer_account"`
 }
 
 func (m *MsgSetDeveloperAccount) Reset()         { *m = MsgSetDeveloperAccount{} }
@@ -218,9 +219,9 @@ var xxx_messageInfo_MsgSetDeveloperAccountResponse proto.InternalMessageInfo
 // MsgSetPoolWeights defines the Msg/SetPoolWeights request type.
 type MsgSetPoolWeights struct {
 	// admin is the account that is authorized to set the pool weights.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// pool_weights is the list of pool weights to set.
-	PoolWeights *PoolWeights `protobuf:"bytes,2,opt,name=pool_weights,json=poolWeights,proto3" json:"pool_weights,omitempty"`
+	PoolWeights PoolWeights `protobuf:"bytes,2,opt,name=pool_weights,json=poolWeights,proto3" json:"pool_weights" yaml:"pool_weights"`
 }
 
 func (m *MsgSetPoolWeights) Reset()         { *m = MsgSetPoolWeights{} }
@@ -263,11 +264,11 @@ func (m *MsgSetPoolWeights) GetAdmin() string {
 	return ""
 }
 
-func (m *MsgSetPoolWeights) GetPoolWeights() *PoolWeights {
+func (m *MsgSetPoolWeights) GetPoolWeights() PoolWeights {
 	if m != nil {
 		return m.PoolWeights
 	}
-	return nil
+	return PoolWeights{}
 }
 
 // MsgSetPoolWeightsResponse defines the Msg/SetPoolWeights response type.
@@ -310,10 +311,10 @@ var xxx_messageInfo_MsgSetPoolWeightsResponse proto.InternalMessageInfo
 // MsgSetMaxPoolPointsPerTx defines the Msg/SetMaxPoolPointsPerTx request type.
 type MsgSetMaxPoolPointsPerTx struct {
 	// admin is the account that is authorized to set the max pool points per tx.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// max_pool_points_per_tx is the maximum number of pool points that can be
 	// consumed per transaction.
-	MaxPoolPointsPerTx uint64 `protobuf:"varint,2,opt,name=max_pool_points_per_tx,json=maxPoolPointsPerTx,proto3" json:"max_pool_points_per_tx,omitempty"`
+	MaxPoolPointsPerTx uint64 `protobuf:"varint,2,opt,name=max_pool_points_per_tx,json=maxPoolPointsPerTx,proto3" json:"max_pool_points_per_tx,omitempty" yaml:"max_pool_points_per_tx"`
 }
 
 func (m *MsgSetMaxPoolPointsPerTx) Reset()         { *m = MsgSetMaxPoolPointsPerTx{} }
@@ -406,10 +407,10 @@ var xxx_messageInfo_MsgSetMaxPoolPointsPerTxResponse proto.InternalMessageInfo
 type MsgSetMaxPoolPointsPerBlock struct {
 	// admin is the account that is authorized to set the max pool points per
 	// block.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// max_pool_points_per_block is the maximum number of pool points that can be
 	// consumed per block.
-	MaxPoolPointsPerBlock uint64 `protobuf:"varint,2,opt,name=max_pool_points_per_block,json=maxPoolPointsPerBlock,proto3" json:"max_pool_points_per_block,omitempty"`
+	MaxPoolPointsPerBlock uint64 `protobuf:"varint,2,opt,name=max_pool_points_per_block,json=maxPoolPointsPerBlock,proto3" json:"max_pool_points_per_block,omitempty" yaml:"max_pool_points_per_block"`
 }
 
 func (m *MsgSetMaxPoolPointsPerBlock) Reset()         { *m = MsgSetMaxPoolPointsPerBlock{} }
@@ -500,9 +501,9 @@ var xxx_messageInfo_MsgSetMaxPoolPointsPerBlockResponse proto.InternalMessageInf
 // MsgSetBaseDenoms defines the Msg/SetBaseDenoms request type.
 type MsgSetBaseDenoms struct {
 	// admin is the account that is authorized to set the base denoms.
-	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty"`
+	Admin string `protobuf:"bytes,1,opt,name=admin,proto3" json:"admin,omitempty" yaml:"admin"`
 	// base_denoms is the list of base denoms to set.
-	BaseDenoms []*BaseDenom `protobuf:"bytes,2,rep,name=base_denoms,json=baseDenoms,proto3" json:"base_denoms,omitempty"`
+	BaseDenoms []BaseDenom `protobuf:"bytes,2,rep,name=base_denoms,json=baseDenoms,proto3" json:"base_denoms" yaml:"base_denoms"`
 }
 
 func (m *MsgSetBaseDenoms) Reset()         { *m = MsgSetBaseDenoms{} }
@@ -545,7 +546,7 @@ func (m *MsgSetBaseDenoms) GetAdmin() string {
 	return ""
 }
 
-func (m *MsgSetBaseDenoms) GetBaseDenoms() []*BaseDenom {
+func (m *MsgSetBaseDenoms) GetBaseDenoms() []BaseDenom {
 	if m != nil {
 		return m.BaseDenoms
 	}
@@ -607,51 +608,59 @@ func init() {
 func init() { proto.RegisterFile("osmosis/protorev/v1beta1/tx.proto", fileDescriptor_2783dce032fc6954) }
 
 var fileDescriptor_2783dce032fc6954 = []byte{
-	// 692 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x3f, 0x6f, 0xd3, 0x4e,
-	0x1c, 0xc6, 0xeb, 0xf6, 0xf7, 0x43, 0xf4, 0x9b, 0x02, 0xad, 0x69, 0x4b, 0xea, 0xa2, 0x28, 0x5c,
-	0xe9, 0x1f, 0x68, 0x6b, 0x37, 0x4e, 0x2b, 0x55, 0x20, 0x86, 0x56, 0x1d, 0x2a, 0xa1, 0xa2, 0xc8,
-	0x54, 0x42, 0x82, 0xc1, 0xb2, 0x93, 0x93, 0x63, 0x35, 0xf6, 0x59, 0xbe, 0x6b, 0x08, 0x2b, 0xaf,
-	0x00, 0x89, 0x8d, 0x81, 0x81, 0xf7, 0x00, 0x3b, 0x1b, 0x0b, 0x52, 0x25, 0x16, 0x46, 0xd4, 0xf2,
-	0x42, 0x50, 0xce, 0xf1, 0x25, 0x4d, 0x7c, 0xa4, 0x61, 0x8b, 0xed, 0xe7, 0xfb, 0x3c, 0x9f, 0xbb,
-	0xcb, 0x73, 0x70, 0x8f, 0xd0, 0x80, 0x50, 0x9f, 0x1a, 0x51, 0x4c, 0x18, 0x89, 0x71, 0xd3, 0x68,
-	0x96, 0x5c, 0xcc, 0x9c, 0x92, 0xc1, 0x5a, 0x3a, 0x7f, 0xa7, 0xe6, 0x3b, 0x12, 0x3d, 0x95, 0xe8,
-	0x1d, 0x89, 0x36, 0xeb, 0x11, 0x8f, 0xf0, 0xb7, 0x46, 0xfb, 0x57, 0x22, 0xd0, 0xee, 0x7a, 0x84,
-	0x78, 0x0d, 0x6c, 0x38, 0x91, 0x6f, 0x38, 0x61, 0x48, 0x98, 0xc3, 0x7c, 0x12, 0x76, 0xc6, 0xb5,
-	0x55, 0x69, 0xa0, 0xb0, 0xe7, 0x3f, 0x10, 0x83, 0x5b, 0x47, 0xd4, 0x7b, 0x8e, 0xd9, 0x21, 0x61,
-	0x16, 0x39, 0x65, 0x98, 0xaa, 0xb3, 0xf0, 0xbf, 0x53, 0x0b, 0xfc, 0x30, 0xaf, 0x14, 0x95, 0xb5,
-	0x49, 0x2b, 0x79, 0x50, 0x9f, 0x02, 0xd4, 0x09, 0xb3, 0x63, 0xae, 0xc9, 0x8f, 0x17, 0x27, 0xd6,
-	0x72, 0xe6, 0x86, 0x2e, 0x83, 0xd6, 0x8f, 0xc9, 0x09, 0x0e, 0x2b, 0x8e, 0x1f, 0xef, 0xc5, 0x6e,
-	0xe2, 0x6b, 0x4d, 0xd6, 0xd3, 0x08, 0xb4, 0x00, 0x77, 0xfa, 0x52, 0x2d, 0x4c, 0x23, 0x12, 0x52,
-	0x8c, 0x5e, 0xc1, 0x7c, 0xf2, 0xe9, 0x00, 0x37, 0x71, 0x83, 0x44, 0x38, 0xde, 0xab, 0x56, 0xc9,
-	0x69, 0xc8, 0x24, 0x5c, 0xeb, 0x30, 0x53, 0x4b, 0x95, 0xb6, 0x93, 0x48, 0xf3, 0xe3, 0x5c, 0x31,
-	0x5d, 0xeb, 0xb3, 0x40, 0x45, 0x28, 0x64, 0x9b, 0x8b, 0x78, 0x0a, 0x33, 0x89, 0xa2, 0x42, 0x48,
-	0xe3, 0x05, 0xf6, 0xbd, 0x3a, 0x93, 0xed, 0xc8, 0x21, 0x4c, 0x45, 0x84, 0x34, 0xec, 0xd7, 0x89,
-	0x8a, 0x87, 0xe6, 0xcc, 0x65, 0xf9, 0x9e, 0xf4, 0x58, 0x5a, 0xb9, 0xa8, 0xfb, 0x80, 0x16, 0x61,
-	0x61, 0x20, 0x54, 0x10, 0xd5, 0x20, 0x9f, 0x7c, 0x3c, 0x72, 0x5a, 0xed, 0xef, 0x15, 0xe2, 0x87,
-	0x8c, 0x56, 0x70, 0x7c, 0xdc, 0x92, 0x80, 0x99, 0x30, 0x1f, 0x38, 0x2d, 0x9b, 0xc3, 0x45, 0x5c,
-	0x6d, 0xb7, 0x37, 0x87, 0xb5, 0x38, 0xe2, 0x7f, 0x96, 0x1a, 0x0c, 0x38, 0x21, 0x04, 0x45, 0x59,
-	0x8a, 0x20, 0x09, 0x60, 0x31, 0x5b, 0xb3, 0xdf, 0x20, 0xd5, 0x13, 0x09, 0xcc, 0x2e, 0x2c, 0x64,
-	0xc1, 0xb8, 0xed, 0x91, 0x0e, 0xcf, 0x5c, 0x90, 0xe5, 0x87, 0x96, 0x61, 0xe9, 0x2f, 0x71, 0x82,
-	0x2a, 0x84, 0xe9, 0x44, 0xb6, 0xef, 0x50, 0x7c, 0x80, 0x43, 0x12, 0xc8, 0x0e, 0xec, 0x00, 0x72,
-	0xae, 0x43, 0xb1, 0x5d, 0xe3, 0xa2, 0xce, 0x7f, 0x78, 0x49, 0x7e, 0x5e, 0xc2, 0xd0, 0x02, 0x57,
-	0x78, 0x23, 0x2d, 0x3d, 0x8f, 0x6e, 0x5e, 0xca, 0x62, 0x7e, 0xbe, 0x0e, 0x13, 0x47, 0xd4, 0x53,
-	0x3f, 0x28, 0x30, 0x75, 0xa9, 0x53, 0x0f, 0xe4, 0x29, 0x7d, 0x45, 0xd0, 0x4a, 0x57, 0x96, 0x8a,
-	0x2d, 0xd8, 0x78, 0xfb, 0xe3, 0xf7, 0xfb, 0xf1, 0x15, 0x74, 0xdf, 0x48, 0x6b, 0xdf, 0x2c, 0x6d,
-	0x77, 0xab, 0x4f, 0x31, 0xb3, 0xbb, 0xdd, 0x55, 0xbf, 0x28, 0x70, 0x3b, 0xab, 0x5f, 0x5b, 0xc3,
-	0x82, 0xfb, 0x27, 0xb4, 0xdd, 0x51, 0x27, 0x04, 0x71, 0x99, 0x13, 0x6f, 0xa2, 0x75, 0x39, 0xf1,
-	0x40, 0xab, 0xd5, 0xaf, 0x0a, 0xcc, 0x65, 0xf7, 0xc0, 0x1c, 0x06, 0x32, 0x38, 0xa3, 0x3d, 0x1a,
-	0x7d, 0x46, 0xe0, 0xef, 0x72, 0x7c, 0x13, 0x6d, 0xc9, 0xf1, 0xb3, 0x1b, 0xa8, 0x7e, 0x57, 0x20,
-	0x2f, 0x6d, 0xd0, 0xce, 0xa8, 0x48, 0x7c, 0x4c, 0x7b, 0xf2, 0x4f, 0x63, 0x62, 0x31, 0x8f, 0xf9,
-	0x62, 0x76, 0x50, 0x79, 0xb4, 0xc5, 0xf0, 0x06, 0xab, 0x9f, 0x14, 0xb8, 0xd9, 0x77, 0x5b, 0xae,
-	0x0f, 0xc3, 0xe9, 0x11, 0x6b, 0xe5, 0x11, 0xc4, 0x82, 0x58, 0xe7, 0xc4, 0x6b, 0x68, 0x45, 0x4e,
-	0xdc, 0x7b, 0x33, 0xab, 0x1f, 0x15, 0xb8, 0x71, 0xf9, 0x82, 0x78, 0x38, 0x2c, 0xb6, 0xab, 0xd5,
-	0xcc, 0xab, 0x6b, 0x05, 0xe1, 0x26, 0x27, 0x5c, 0x45, 0xcb, 0x72, 0xc2, 0x9e, 0xab, 0x68, 0xff,
-	0xd9, 0xb7, 0xf3, 0x82, 0x72, 0x76, 0x5e, 0x50, 0x7e, 0x9d, 0x17, 0x94, 0x77, 0x17, 0x85, 0xb1,
-	0xb3, 0x8b, 0xc2, 0xd8, 0xcf, 0x8b, 0xc2, 0xd8, 0xcb, 0x6d, 0xcf, 0x67, 0xf5, 0x53, 0x57, 0xaf,
-	0x92, 0x20, 0xb5, 0xda, 0x6c, 0x38, 0x2e, 0xed, 0xf1, 0xdd, 0x31, 0x5a, 0x5d, 0x67, 0xf6, 0x26,
-	0xc2, 0xd4, 0xbd, 0xc6, 0x9f, 0xcb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x84, 0xe0, 0x5d,
-	0x78, 0x08, 0x00, 0x00,
+	// 819 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xcf, 0x6e, 0xeb, 0x44,
+	0x14, 0xc6, 0x33, 0xbd, 0x80, 0xb8, 0x93, 0x02, 0xb7, 0xbe, 0x6d, 0x49, 0xdc, 0x92, 0xa4, 0xd3,
+	0x7f, 0x81, 0x36, 0x71, 0x93, 0xb4, 0x52, 0x55, 0x04, 0x52, 0xad, 0x2e, 0x60, 0x51, 0x14, 0xb9,
+	0x45, 0x48, 0x2c, 0x30, 0x76, 0x32, 0x38, 0x56, 0x63, 0x8f, 0xe5, 0x99, 0x86, 0x74, 0xcb, 0x13,
+	0x20, 0xb1, 0x63, 0xc1, 0x02, 0x9e, 0x00, 0xa9, 0x20, 0x81, 0xc4, 0x82, 0x5d, 0x37, 0x48, 0x15,
+	0x6c, 0x58, 0x45, 0xa8, 0xe5, 0x09, 0xf2, 0x04, 0x28, 0x33, 0x8e, 0x93, 0x26, 0x36, 0x69, 0x6e,
+	0x76, 0xf1, 0xcc, 0x77, 0xbe, 0xf3, 0xfb, 0x32, 0xe3, 0x63, 0xb8, 0x46, 0xa8, 0x43, 0xa8, 0x4d,
+	0x15, 0xcf, 0x27, 0x8c, 0xf8, 0xb8, 0xa5, 0xb4, 0x4a, 0x26, 0x66, 0x46, 0x49, 0x61, 0xed, 0x22,
+	0x5f, 0x93, 0x52, 0x81, 0xa4, 0xd8, 0x97, 0x14, 0x03, 0x89, 0xbc, 0x68, 0x11, 0x8b, 0xf0, 0x55,
+	0xa5, 0xf7, 0x4b, 0x08, 0xe4, 0x55, 0x8b, 0x10, 0xab, 0x89, 0x15, 0xc3, 0xb3, 0x15, 0xc3, 0x75,
+	0x09, 0x33, 0x98, 0x4d, 0xdc, 0xa0, 0x5c, 0xde, 0x8e, 0x6d, 0x18, 0xda, 0x0b, 0x61, 0xba, 0xc6,
+	0x95, 0xba, 0xf0, 0x17, 0x0f, 0x62, 0x0b, 0xfd, 0x02, 0xe0, 0x1b, 0xa7, 0xd4, 0x3a, 0xc3, 0xec,
+	0x03, 0xc2, 0x34, 0x72, 0xc9, 0x30, 0x95, 0xde, 0x87, 0x2f, 0x1b, 0x75, 0xc7, 0x76, 0x53, 0x20,
+	0x07, 0xf2, 0x4f, 0xd5, 0x7c, 0xb7, 0x93, 0x9d, 0xbf, 0x32, 0x9c, 0xe6, 0x11, 0xe2, 0xcb, 0xe8,
+	0xcf, 0xeb, 0xc2, 0x62, 0x60, 0x72, 0x5c, 0xaf, 0xfb, 0x98, 0xd2, 0x33, 0xe6, 0xdb, 0xae, 0xa5,
+	0x89, 0x32, 0xe9, 0x0b, 0x08, 0x1b, 0x84, 0xe9, 0x3e, 0x77, 0x4b, 0xcd, 0xe5, 0x9e, 0xe4, 0x93,
+	0xe5, 0xdd, 0x62, 0x5c, 0xf4, 0xe2, 0x39, 0xb9, 0xc0, 0x6e, 0xd5, 0xb0, 0xfd, 0x63, 0xdf, 0x14,
+	0x04, 0x6a, 0xfa, 0xa6, 0x93, 0x4d, 0x74, 0x3b, 0xd9, 0x05, 0xd1, 0x76, 0xe0, 0x86, 0xb4, 0xa7,
+	0x8d, 0x3e, 0x27, 0x4a, 0xc3, 0x37, 0x47, 0xd0, 0x35, 0x4c, 0x3d, 0xe2, 0x52, 0x8c, 0x7e, 0x00,
+	0x70, 0x59, 0xec, 0x9d, 0xe0, 0x16, 0x6e, 0x12, 0x0f, 0xfb, 0xc7, 0xb5, 0x1a, 0xb9, 0x74, 0xd9,
+	0xcc, 0xe9, 0x3e, 0x84, 0x0b, 0xf5, 0xbe, 0xa7, 0x6e, 0x08, 0xd3, 0xd4, 0x1c, 0xf7, 0x5a, 0xed,
+	0x76, 0xb2, 0x29, 0xe1, 0x35, 0x26, 0x41, 0xda, 0xb3, 0xfa, 0x08, 0x0a, 0xca, 0xc1, 0x4c, 0x34,
+	0x64, 0x98, 0xe3, 0x57, 0x00, 0x17, 0x84, 0xa4, 0x4a, 0x48, 0xf3, 0x13, 0x6c, 0x5b, 0x0d, 0x36,
+	0xfb, 0x01, 0x61, 0x38, 0xef, 0x11, 0xd2, 0xd4, 0xbf, 0x14, 0x7e, 0x9c, 0x3e, 0x59, 0xde, 0x8c,
+	0x3f, 0xa2, 0xa1, 0xe6, 0xea, 0x4a, 0x70, 0x36, 0xcf, 0x45, 0xc7, 0x61, 0x23, 0xa4, 0x25, 0xbd,
+	0x81, 0x12, 0xad, 0xc0, 0xf4, 0x18, 0x7b, 0x98, 0xec, 0x47, 0x00, 0x53, 0x62, 0xf7, 0xd4, 0x68,
+	0xf7, 0x04, 0x55, 0x62, 0xbb, 0x8c, 0x56, 0xb1, 0x7f, 0xde, 0x9e, 0x39, 0xe0, 0xc7, 0x70, 0xd9,
+	0x31, 0xda, 0x3a, 0x67, 0xf3, 0xb8, 0xaf, 0xde, 0x3b, 0x0a, 0xd6, 0xe6, 0x51, 0x5f, 0x52, 0xd7,
+	0xba, 0x9d, 0xec, 0x5b, 0xc2, 0x30, 0x5a, 0x87, 0x34, 0xc9, 0x19, 0xc3, 0x42, 0x08, 0xe6, 0xe2,
+	0x90, 0xc3, 0x5c, 0xbf, 0x01, 0xb8, 0x12, 0x2d, 0x52, 0x9b, 0xa4, 0x76, 0x31, 0x73, 0xb4, 0xcf,
+	0x60, 0x3a, 0x0a, 0xd9, 0xec, 0x99, 0x07, 0xe9, 0x36, 0xba, 0x9d, 0x6c, 0x2e, 0x3e, 0x1d, 0x97,
+	0x22, 0x6d, 0xc9, 0x89, 0xe2, 0x43, 0x9b, 0x70, 0xfd, 0x7f, 0xf0, 0xc3, 0x98, 0xd7, 0x00, 0x3e,
+	0x13, 0x3a, 0xd5, 0xa0, 0xf8, 0x04, 0xbb, 0xc4, 0x99, 0xfd, 0x5e, 0x7e, 0x0e, 0x93, 0xa6, 0x41,
+	0xb1, 0x5e, 0xe7, 0x76, 0xc1, 0xe4, 0x58, 0x8f, 0xbf, 0x96, 0x61, 0x6b, 0x55, 0x0e, 0x2e, 0xa5,
+	0x24, 0xda, 0x0d, 0xb9, 0x20, 0x0d, 0x9a, 0x21, 0x21, 0x92, 0xfb, 0x97, 0x6e, 0x40, 0xdd, 0x8f,
+	0x54, 0xfe, 0xe9, 0x55, 0xf8, 0xe4, 0x94, 0x5a, 0xd2, 0xb7, 0x00, 0xce, 0x3f, 0x98, 0x87, 0x6f,
+	0xc7, 0x13, 0x8c, 0xcc, 0x1f, 0xb9, 0xf4, 0x68, 0x69, 0xf8, 0x4f, 0xee, 0x7e, 0xf5, 0xd7, 0xbf,
+	0xdf, 0xcc, 0x6d, 0xa1, 0x0d, 0xa5, 0x3f, 0xce, 0x5b, 0xa5, 0xfd, 0xc1, 0x48, 0xa7, 0x98, 0xe9,
+	0x83, 0xf9, 0x27, 0xfd, 0x0c, 0xe0, 0xf3, 0xa8, 0xa9, 0xb6, 0x37, 0xa9, 0xf1, 0x68, 0x85, 0x7c,
+	0x38, 0x6d, 0x45, 0x48, 0x5c, 0xe1, 0xc4, 0x05, 0xb4, 0x13, 0x4f, 0x3c, 0x36, 0xfe, 0xa4, 0xdf,
+	0x01, 0x5c, 0x8a, 0x7e, 0xd9, 0xcb, 0x93, 0x40, 0xc6, 0x6b, 0xe4, 0xa3, 0xe9, 0x6b, 0x42, 0xfc,
+	0x43, 0x8e, 0x5f, 0x46, 0x7b, 0xf1, 0xf8, 0xd1, 0x43, 0x41, 0xfa, 0x03, 0xc0, 0x54, 0xec, 0x8b,
+	0x7d, 0x30, 0x2d, 0x12, 0x2f, 0x93, 0xdf, 0x7b, 0xa1, 0xb2, 0x30, 0xcc, 0xbb, 0x3c, 0xcc, 0x01,
+	0xaa, 0x4c, 0x17, 0x86, 0xcf, 0x00, 0xe9, 0x7b, 0x00, 0x5f, 0x1f, 0xf9, 0xb4, 0xec, 0x4c, 0xc2,
+	0x19, 0x12, 0xcb, 0x95, 0x29, 0xc4, 0x21, 0x71, 0x91, 0x13, 0xe7, 0xd1, 0x56, 0x3c, 0xf1, 0xf0,
+	0x37, 0x45, 0xfa, 0x0e, 0xc0, 0xd7, 0x1e, 0x8e, 0x99, 0x77, 0x26, 0xb5, 0x1d, 0x68, 0xe5, 0xf2,
+	0xe3, 0xb5, 0x21, 0x61, 0x81, 0x13, 0x6e, 0xa3, 0xcd, 0x78, 0xc2, 0xa1, 0x01, 0xa3, 0x7e, 0x74,
+	0x73, 0x97, 0x01, 0xb7, 0x77, 0x19, 0xf0, 0xcf, 0x5d, 0x06, 0x7c, 0x7d, 0x9f, 0x49, 0xdc, 0xde,
+	0x67, 0x12, 0x7f, 0xdf, 0x67, 0x12, 0x9f, 0xee, 0x5b, 0x36, 0x6b, 0x5c, 0x9a, 0xc5, 0x1a, 0x71,
+	0xfa, 0x56, 0x85, 0xa6, 0x61, 0xd2, 0x21, 0xdf, 0x03, 0xa5, 0x3d, 0x70, 0x66, 0x57, 0x1e, 0xa6,
+	0xe6, 0x2b, 0xfc, 0xb9, 0xf2, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x2f, 0x94, 0x55, 0x50,
+	0x0a, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -1085,18 +1094,16 @@ func (m *MsgSetPoolWeights) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 	_ = i
 	var l int
 	_ = l
-	if m.PoolWeights != nil {
-		{
-			size, err := m.PoolWeights.MarshalToSizedBuffer(dAtA[:i])
-			if err != nil {
-				return 0, err
-			}
-			i -= size
-			i = encodeVarintTx(dAtA, i, uint64(size))
+	{
+		size, err := m.PoolWeights.MarshalToSizedBuffer(dAtA[:i])
+		if err != nil {
+			return 0, err
 		}
-		i--
-		dAtA[i] = 0x12
+		i -= size
+		i = encodeVarintTx(dAtA, i, uint64(size))
 	}
+	i--
+	dAtA[i] = 0x12
 	if len(m.Admin) > 0 {
 		i -= len(m.Admin)
 		copy(dAtA[i:], m.Admin)
@@ -1388,10 +1395,8 @@ func (m *MsgSetPoolWeights) Size() (n int) {
 	if l > 0 {
 		n += 1 + l + sovTx(uint64(l))
 	}
-	if m.PoolWeights != nil {
-		l = m.PoolWeights.Size()
-		n += 1 + l + sovTx(uint64(l))
-	}
+	l = m.PoolWeights.Size()
+	n += 1 + l + sovTx(uint64(l))
 	return n
 }
 
@@ -1578,7 +1583,7 @@ func (m *MsgSetHotRoutes) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.HotRoutes = append(m.HotRoutes, &TokenPairArbRoutes{})
+			m.HotRoutes = append(m.HotRoutes, TokenPairArbRoutes{})
 			if err := m.HotRoutes[len(m.HotRoutes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -1908,9 +1913,6 @@ func (m *MsgSetPoolWeights) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			if m.PoolWeights == nil {
-				m.PoolWeights = &PoolWeights{}
-			}
 			if err := m.PoolWeights.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -2378,7 +2380,7 @@ func (m *MsgSetBaseDenoms) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.BaseDenoms = append(m.BaseDenoms, &BaseDenom{})
+			m.BaseDenoms = append(m.BaseDenoms, BaseDenom{})
 			if err := m.BaseDenoms[len(m.BaseDenoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
diff --git a/x/protorev/types/validate.go b/x/protorev/types/validate.go
new file mode 100644
index 000000000..65f752539
--- /dev/null
+++ b/x/protorev/types/validate.go
@@ -0,0 +1,94 @@
+package types
+
+import (
+	fmt "fmt"
+
+	sdk "github.com/cosmos/cosmos-sdk/types"
+)
+
+// ---------------------- BaseDenom Validation ---------------------- //
+// Validates the base denoms that are used to generate highest liquidity routes.
+func (base *BaseDenom) Validate() error {
+	if base.Denom == "" {
+		return fmt.Errorf("base denom cannot be empty")
+	}
+
+	if base.StepSize.IsNil() || base.StepSize.LT(sdk.OneInt()) {
+		return fmt.Errorf("step size must be greater than 0")
+	}
+
+	return nil
+}
+
+// ValidateBaseDenoms validates the base denoms that are used to generate highest liquidity routes.
+func ValidateBaseDenoms(denoms []BaseDenom) error {
+	// The first base denom must be the Osmosis denomination
+	if len(denoms) == 0 || denoms[0].Denom != OsmosisDenomination {
+		return fmt.Errorf("the first base denom must be the Osmosis denomination")
+	}
+
+	seenDenoms := make(map[string]bool)
+	for _, denom := range denoms {
+		if err := denom.Validate(); err != nil {
+			return err
+		}
+
+		// Ensure that the base denom is unique
+		if seenDenoms[denom.Denom] {
+			return fmt.Errorf("duplicate base denom %s", denom)
+		}
+		seenDenoms[denom.Denom] = true
+	}
+	return nil
+}
+
+// ---------------------- PoolWeights Validation ---------------------- //
+// Validates that the pool weights object is ready for use in the module.
+func (pw *PoolWeights) Validate() error {
+	if pw == nil {
+		return fmt.Errorf("pool weights cannot be nil")
+	}
+
+	if pw.BalancerWeight == 0 || pw.StableWeight == 0 || pw.ConcentratedWeight == 0 {
+		return fmt.Errorf("pool weights cannot be 0")
+	}
+
+	return nil
+}
+
+// ---------------------- DeveloperFee Validation ---------------------- //
+// ValidateDeveloperFees does some basic validation on the developer fees passed into the module genesis.
+func ValidateDeveloperFees(fees []sdk.Coin) error {
+	seenDenoms := make(map[string]bool)
+	for _, fee := range fees {
+		if err := fee.Validate(); err != nil {
+			return err
+		}
+
+		// Ensure that the developer fee is unique
+		if seenDenoms[fee.Denom] {
+			return fmt.Errorf("duplicate developer fee %s", fee)
+		}
+		seenDenoms[fee.Denom] = true
+	}
+	return nil
+}
+
+// ---------------------- Pool Point Validation ---------------------- //
+// ValidateMaxPoolPointsPerBlock validates the max pool points per block.
+func ValidateMaxPoolPointsPerBlock(points uint64) error {
+	if points == 0 || points > MaxPoolPointsPerBlock {
+		return fmt.Errorf("max pool points per block must be between 1 and %d", MaxPoolPointsPerBlock)
+	}
+
+	return nil
+}
+
+// ValidateMaxPoolPointsPerTx validates the max pool points per tx.
+func ValidateMaxPoolPointsPerTx(points uint64) error {
+	if points == 0 || points > MaxPoolPointsPerTx {
+		return fmt.Errorf("max pool points per tx must be between 1 and %d", MaxPoolPointsPerTx)
+	}
+
+	return nil
+}


Test patch:
diff --git a/tests/e2e/configurer/chain/queries.go b/tests/e2e/configurer/chain/queries.go
index a6b636018..791cb2dc5 100644
--- a/tests/e2e/configurer/chain/queries.go
+++ b/tests/e2e/configurer/chain/queries.go
@@ -46,12 +46,12 @@ func (n *NodeConfig) QueryProtoRevNumberOfTrades() (sdk.Int, error) {
 }
 
 // QueryProtoRevProfits gets the profits the protorev module has made.
-func (n *NodeConfig) QueryProtoRevProfits() ([]*sdk.Coin, error) {
+func (n *NodeConfig) QueryProtoRevProfits() ([]sdk.Coin, error) {
 	path := "/osmosis/v14/protorev/all_profits"
 
 	bz, err := n.QueryGRPCGateway(path)
 	if err != nil {
-		return []*sdk.Coin{}, err
+		return []sdk.Coin{}, err
 	}
 
 	// nolint: staticcheck
@@ -78,12 +78,12 @@ func (n *NodeConfig) QueryProtoRevAllRouteStatistics() ([]protorevtypes.RouteSta
 }
 
 // QueryProtoRevTokenPairArbRoutes gets all of the token pair hot routes that the module is currently using.
-func (n *NodeConfig) QueryProtoRevTokenPairArbRoutes() ([]*protorevtypes.TokenPairArbRoutes, error) {
+func (n *NodeConfig) QueryProtoRevTokenPairArbRoutes() ([]protorevtypes.TokenPairArbRoutes, error) {
 	path := "/osmosis/v14/protorev/token_pair_arb_routes"
 
 	bz, err := n.QueryGRPCGateway(path)
 	if err != nil {
-		return []*protorevtypes.TokenPairArbRoutes{}, err
+		return []protorevtypes.TokenPairArbRoutes{}, err
 	}
 
 	// nolint: staticcheck
@@ -116,12 +116,12 @@ func (n *NodeConfig) QueryProtoRevDeveloperAccount() (sdk.AccAddress, error) {
 }
 
 // QueryProtoRevPoolWeights gets the pool point weights of the module.
-func (n *NodeConfig) QueryProtoRevPoolWeights() (*protorevtypes.PoolWeights, error) {
+func (n *NodeConfig) QueryProtoRevPoolWeights() (protorevtypes.PoolWeights, error) {
 	path := "/osmosis/v14/protorev/pool_weights"
 
 	bz, err := n.QueryGRPCGateway(path)
 	if err != nil {
-		return nil, err
+		return protorevtypes.PoolWeights{}, err
 	}
 
 	// nolint: staticcheck
@@ -164,12 +164,12 @@ func (n *NodeConfig) QueryProtoRevMaxPoolPointsPerBlock() (uint64, error) {
 }
 
 // QueryProtoRevBaseDenoms gets the base denoms used to construct cyclic arbitrage routes.
-func (n *NodeConfig) QueryProtoRevBaseDenoms() ([]*protorevtypes.BaseDenom, error) {
+func (n *NodeConfig) QueryProtoRevBaseDenoms() ([]protorevtypes.BaseDenom, error) {
 	path := "/osmosis/v14/protorev/base_denoms"
 
 	bz, err := n.QueryGRPCGateway(path)
 	if err != nil {
-		return []*protorevtypes.BaseDenom{}, err
+		return []protorevtypes.BaseDenom{}, err
 	}
 
 	// nolint: staticcheck
diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go
index 314e68756..e9bcae681 100644
--- a/tests/e2e/e2e_test.go
+++ b/tests/e2e/e2e_test.go
@@ -80,7 +80,7 @@ func (s *IntegrationTestSuite) TestProtoRev() {
 
 	// The module should have pool weights by default.
 	poolWeights, err := chainANode.QueryProtoRevPoolWeights()
-	s.T().Logf("checking that the protorev module has pool weights on init: %s", poolWeights)
+	s.T().Logf("checking that the protorev module has pool weights on init: %v", poolWeights)
 	s.Require().NoError(err)
 	s.Require().NotNil(poolWeights)
 
diff --git a/x/protorev/keeper/epoch_hook_test.go b/x/protorev/keeper/epoch_hook_test.go
index 4d90a1c1c..cc3f3f88c 100644
--- a/x/protorev/keeper/epoch_hook_test.go
+++ b/x/protorev/keeper/epoch_hook_test.go
@@ -117,7 +117,7 @@ func (suite *KeeperTestSuite) TestEpochHook() {
 	suite.Require().Equal(totalNumberExpected, totalActuallySeen)
 }
 
-func contains(baseDenoms []*types.BaseDenom, denomToMatch string) bool {
+func contains(baseDenoms []types.BaseDenom, denomToMatch string) bool {
 	for _, baseDenom := range baseDenoms {
 		if baseDenom.Denom == denomToMatch {
 			return true
diff --git a/x/protorev/keeper/genesis_test.go b/x/protorev/keeper/genesis_test.go
new file mode 100644
index 000000000..5f80316e5
--- /dev/null
+++ b/x/protorev/keeper/genesis_test.go
@@ -0,0 +1,58 @@
+package keeper_test
+
+// TestInitGenesis tests the initialization and export of the module's genesis state.
+func (suite *KeeperTestSuite) TestInitGenesis() {
+	// Export the genesis state
+	exportedGenesis := suite.App.ProtoRevKeeper.ExportGenesis(suite.Ctx)
+
+	// ------ Check that the exported genesis state matches the keeper test genesis state ------ //
+	tokenPairArbRoutes, err := suite.App.ProtoRevKeeper.GetAllTokenPairArbRoutes(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(len(tokenPairArbRoutes), len(exportedGenesis.TokenPairArbRoutes))
+	for _, route := range exportedGenesis.TokenPairArbRoutes {
+		suite.Require().Contains(tokenPairArbRoutes, route)
+	}
+
+	baseDenoms, err := suite.App.ProtoRevKeeper.GetAllBaseDenoms(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(len(baseDenoms), len(exportedGenesis.BaseDenoms))
+	for _, baseDenom := range exportedGenesis.BaseDenoms {
+		suite.Require().Contains(baseDenoms, baseDenom)
+	}
+
+	params := suite.App.ProtoRevKeeper.GetParams(suite.Ctx)
+	suite.Require().Equal(params, exportedGenesis.Params)
+
+	poolWeights := suite.App.ProtoRevKeeper.GetPoolWeights(suite.Ctx)
+	suite.Require().Equal(poolWeights, exportedGenesis.PoolWeights)
+
+	daysSinceGenesis, err := suite.App.ProtoRevKeeper.GetDaysSinceModuleGenesis(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(daysSinceGenesis, exportedGenesis.DaysSinceModuleGenesis)
+
+	developerFees, err := suite.App.ProtoRevKeeper.GetAllDeveloperFees(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(len(developerFees), len(exportedGenesis.DeveloperFees))
+	for _, fee := range exportedGenesis.DeveloperFees {
+		suite.Require().Contains(developerFees, fee)
+	}
+
+	developerAddress, _ := suite.App.ProtoRevKeeper.GetDeveloperAccount(suite.Ctx)
+	suite.Require().Equal(developerAddress.String(), exportedGenesis.DeveloperAddress)
+
+	latestBlockHeight, err := suite.App.ProtoRevKeeper.GetLatestBlockHeight(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(latestBlockHeight, exportedGenesis.LatestBlockHeight)
+
+	maxPoolPointsPerTx, err := suite.App.ProtoRevKeeper.GetMaxPointsPerTx(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(maxPoolPointsPerTx, exportedGenesis.MaxPoolPointsPerTx)
+
+	maxPoolPointsPerBlock, err := suite.App.ProtoRevKeeper.GetMaxPointsPerBlock(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(maxPoolPointsPerBlock, exportedGenesis.MaxPoolPointsPerBlock)
+
+	pointCount, err := suite.App.ProtoRevKeeper.GetPointCountForBlock(suite.Ctx)
+	suite.Require().NoError(err)
+	suite.Require().Equal(pointCount, exportedGenesis.PointCountForBlock)
+}
diff --git a/x/protorev/keeper/grpc_query_test.go b/x/protorev/keeper/grpc_query_test.go
index 746777dff..18f8c4854 100644
--- a/x/protorev/keeper/grpc_query_test.go
+++ b/x/protorev/keeper/grpc_query_test.go
@@ -12,7 +12,7 @@ import (
 // TestParams tests the query for params
 func (suite *KeeperTestSuite) TestParams() {
 	ctx := sdk.WrapSDKContext(suite.Ctx)
-	expectedParams := types.DefaultParams()
+	expectedParams := suite.App.ProtoRevKeeper.GetParams(suite.Ctx)
 
 	res, err := suite.queryClient.Params(ctx, &types.QueryParamsRequest{})
 	suite.Require().NoError(err)
@@ -101,8 +101,8 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllProfits() {
 	suite.Require().NoError(err)
 	atom := sdk.NewCoin("Atom", sdk.NewInt(3000))
 	osmo := sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(9000))
-	suite.Require().Contains(res.Profits, &atom)
-	suite.Require().Contains(res.Profits, &osmo)
+	suite.Require().Contains(res.Profits, atom)
+	suite.Require().Contains(res.Profits, osmo)
 
 	// Pseudo execute more trades
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{}, types.OsmosisDenomination, sdk.NewInt(10000))
@@ -114,8 +114,8 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllProfits() {
 	suite.Require().NoError(err)
 	atom = sdk.NewCoin("Atom", sdk.NewInt(13000))
 	osmo = sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(19000))
-	suite.Require().Contains(res.Profits, &atom)
-	suite.Require().Contains(res.Profits, &osmo)
+	suite.Require().Contains(res.Profits, atom)
+	suite.Require().Contains(res.Profits, osmo)
 }
 
 // TestGetProtoRevStatisticsByRoute tests the query for statistics by route
@@ -139,7 +139,7 @@ func (suite *KeeperTestSuite) TestGetProtoRevStatisticsByRoute() {
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics.Route)
 	suite.Require().Equal(sdk.OneInt(), res.Statistics.NumberOfTrades)
 	coin := sdk.NewCoin("Atom", sdk.NewInt(10000))
-	suite.Require().Contains(res.Statistics.Profits, &coin)
+	suite.Require().Contains(res.Statistics.Profits, coin)
 
 	// Pseudo execute another trade
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{{TokenOutDenom: "", PoolId: 1}, {TokenOutDenom: "", PoolId: 2}, {TokenOutDenom: "", PoolId: 3}}, "Atom", sdk.NewInt(80000))
@@ -151,7 +151,7 @@ func (suite *KeeperTestSuite) TestGetProtoRevStatisticsByRoute() {
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics.Route)
 	suite.Require().Equal(sdk.NewInt(2), res.Statistics.NumberOfTrades)
 	coin = sdk.NewCoin("Atom", sdk.NewInt(90000))
-	suite.Require().Contains(res.Statistics.Profits, &coin)
+	suite.Require().Contains(res.Statistics.Profits, coin)
 
 	// Pseudo execute another trade in a different denom (might happen in multidenom pools > 2 denoms)
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{{TokenOutDenom: "", PoolId: 1}, {TokenOutDenom: "", PoolId: 2}, {TokenOutDenom: "", PoolId: 3}}, types.OsmosisDenomination, sdk.NewInt(80000))
@@ -164,8 +164,8 @@ func (suite *KeeperTestSuite) TestGetProtoRevStatisticsByRoute() {
 	suite.Require().Equal(sdk.NewInt(3), res.Statistics.NumberOfTrades)
 	atomCoin := sdk.NewCoin("Atom", sdk.NewInt(90000))
 	osmoCoin := sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(80000))
-	suite.Require().Contains(res.Statistics.Profits, &atomCoin)
-	suite.Require().Contains(res.Statistics.Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics.Profits, atomCoin)
+	suite.Require().Contains(res.Statistics.Profits, osmoCoin)
 }
 
 // TestGetProtoRevAllRouteStatistics tests the query for all route statistics
@@ -187,7 +187,7 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllRouteStatistics() {
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics[0].Route)
 	suite.Require().Equal(sdk.OneInt(), res.Statistics[0].NumberOfTrades)
 	osmoCoin := sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(10000))
-	suite.Require().Contains(res.Statistics[0].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[0].Profits, osmoCoin)
 
 	// Pseudo execute another trade
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{{TokenOutDenom: "", PoolId: 1}, {TokenOutDenom: "", PoolId: 2}, {TokenOutDenom: "", PoolId: 3}}, types.OsmosisDenomination, sdk.NewInt(80000))
@@ -200,7 +200,7 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllRouteStatistics() {
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics[0].Route)
 	suite.Require().Equal(sdk.NewInt(2), res.Statistics[0].NumberOfTrades)
 	osmoCoin = sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(90000))
-	suite.Require().Contains(res.Statistics[0].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[0].Profits, osmoCoin)
 
 	// Pseudo execute another trade on a different route
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{{TokenOutDenom: "", PoolId: 1}, {TokenOutDenom: "", PoolId: 2}, {TokenOutDenom: "", PoolId: 4}}, types.OsmosisDenomination, sdk.NewInt(70000))
@@ -212,12 +212,12 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllRouteStatistics() {
 	suite.Require().Equal(2, len(res.Statistics))
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics[0].Route)
 	suite.Require().Equal(sdk.NewInt(2), res.Statistics[0].NumberOfTrades)
-	suite.Require().Contains(res.Statistics[0].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[0].Profits, osmoCoin)
 
 	suite.Require().Equal([]uint64{1, 2, 4}, res.Statistics[1].Route)
 	suite.Require().Equal(sdk.OneInt(), res.Statistics[1].NumberOfTrades)
 	osmoCoin = sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(70000))
-	suite.Require().Contains(res.Statistics[1].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[1].Profits, osmoCoin)
 
 	// Pseudo execute another trade on a different route and denom
 	err = suite.App.AppKeepers.ProtoRevKeeper.UpdateStatistics(suite.Ctx, poolmanagertypes.SwapAmountInRoutes{{TokenOutDenom: "", PoolId: 5}, {TokenOutDenom: "", PoolId: 2}, {TokenOutDenom: "", PoolId: 4}}, "Atom", sdk.NewInt(80000))
@@ -230,17 +230,17 @@ func (suite *KeeperTestSuite) TestGetProtoRevAllRouteStatistics() {
 	suite.Require().Equal([]uint64{1, 2, 3}, res.Statistics[0].Route)
 	suite.Require().Equal(sdk.NewInt(2), res.Statistics[0].NumberOfTrades)
 	osmoCoin = sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(90000))
-	suite.Require().Contains(res.Statistics[0].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[0].Profits, osmoCoin)
 
 	suite.Require().Equal([]uint64{1, 2, 4}, res.Statistics[1].Route)
 	suite.Require().Equal(sdk.OneInt(), res.Statistics[1].NumberOfTrades)
 	osmoCoin = sdk.NewCoin(types.OsmosisDenomination, sdk.NewInt(70000))
-	suite.Require().Contains(res.Statistics[1].Profits, &osmoCoin)
+	suite.Require().Contains(res.Statistics[1].Profits, osmoCoin)
 
 	suite.Require().Equal([]uint64{5, 2, 4}, res.Statistics[2].Route)
 	suite.Require().Equal(sdk.OneInt(), res.Statistics[2].NumberOfTrades)
 	atomCoin := sdk.NewCoin("Atom", sdk.NewInt(80000))
-	suite.Require().Contains(res.Statistics[2].Profits, &atomCoin)
+	suite.Require().Contains(res.Statistics[2].Profits, atomCoin)
 }
 
 // TestGetProtoRevTokenPairArbRoutes tests the query to retrieve all token pair arb routes
@@ -295,7 +295,7 @@ func (suite *KeeperTestSuite) TestGetProtoRevPoolWeights() {
 	req := &types.QueryGetProtoRevPoolWeightsRequest{}
 	res, err := suite.queryClient.GetProtoRevPoolWeights(sdk.WrapSDKContext(suite.Ctx), req)
 	suite.Require().NoError(err)
-	suite.Require().Equal(&poolWeights, res.PoolWeights)
+	suite.Require().Equal(poolWeights, res.PoolWeights)
 }
 
 // TestGetProtoRevMaxPoolPointsPerTx tests the query to retrieve the max pool points per tx
diff --git a/x/protorev/keeper/keeper_test.go b/x/protorev/keeper/keeper_test.go
index 4cd2c5e09..7f2294105 100644
--- a/x/protorev/keeper/keeper_test.go
+++ b/x/protorev/keeper/keeper_test.go
@@ -30,7 +30,7 @@ type KeeperTestSuite struct {
 	pools              []Pool
 	stableSwapPools    []StableSwapPool
 	balances           sdk.Coins
-	tokenPairArbRoutes []*types.TokenPairArbRoutes
+	tokenPairArbRoutes []types.TokenPairArbRoutes
 	adminAccount       sdk.AccAddress
 }
 
@@ -58,6 +58,10 @@ func TestKeeperTestSuite(t *testing.T) {
 func (suite *KeeperTestSuite) SetupTest() {
 	suite.Setup()
 
+	// Genesis on init should be the same as the default genesis
+	exportDefaultGenesis := suite.App.ProtoRevKeeper.ExportGenesis(suite.Ctx)
+	suite.Require().Equal(exportDefaultGenesis, types.DefaultGenesis())
+
 	// Init module state for testing (params may differ from default params)
 	suite.App.ProtoRevKeeper.SetProtoRevEnabled(suite.Ctx, true)
 	suite.App.ProtoRevKeeper.SetDaysSinceModuleGenesis(suite.Ctx, 0)
@@ -83,7 +87,7 @@ func (suite *KeeperTestSuite) SetupTest() {
 	suite.App.ProtoRevKeeper.SetPoolWeights(suite.Ctx, poolWeights)
 
 	// Configure the initial base denoms used for cyclic route building
-	baseDenomPriorities := []*types.BaseDenom{
+	baseDenomPriorities := []types.BaseDenom{
 		{
 			Denom:    types.OsmosisDenomination,
 			StepSize: sdk.NewInt(1_000_000),
@@ -925,64 +929,64 @@ func (suite *KeeperTestSuite) setUpTokenPairRoutes() {
 
 	standardStepSize := sdk.NewInt(1_000_000)
 
-	suite.tokenPairArbRoutes = []*types.TokenPairArbRoutes{
+	suite.tokenPairArbRoutes = []types.TokenPairArbRoutes{
 		{
 			TokenIn:  "akash",
 			TokenOut: "Atom",
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&atomAkash, &akashBitcoin, &atomBitcoin},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{atomAkash, akashBitcoin, atomBitcoin},
 				},
 			},
 		},
 		{
 			TokenIn:  "usdc",
 			TokenOut: types.OsmosisDenomination,
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&uosmoUSDC, &usdcBUSD, &busdUOSMO},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{uosmoUSDC, usdcBUSD, busdUOSMO},
 				},
 			},
 		},
 		{
 			TokenIn:  "Atom",
 			TokenOut: "ibc/A0CC0CF735BFB30E730C70019D4218A1244FF383503FF7579C9201AB93CA9293",
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&atomIBC1, &ibc1IBC2, &ibc2ATOM},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{atomIBC1, ibc1IBC2, ibc2ATOM},
 				},
 			},
 		},
 		{
 			TokenIn:  "Atom",
 			TokenOut: "test/2",
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&fourPool0, &fourPool1, &fourPool2, &fourPool3},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{fourPool0, fourPool1, fourPool2, fourPool3},
 				},
 			},
 		},
 		{
 			TokenIn:  types.OsmosisDenomination,
 			TokenOut: "test/3",
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&twoPool0, &twoPool1},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{twoPool0, twoPool1},
 				},
 			},
 		},
 		{
 			TokenIn:  "busd",
 			TokenOut: "usdc",
-			ArbRoutes: []*types.Route{
+			ArbRoutes: []types.Route{
 				{
-					StepSize: &standardStepSize,
-					Trades:   []*types.Trade{&doomsdayStable0, &doomsdayStable1, &doomsdayStable2},
+					StepSize: standardStepSize,
+					Trades:   []types.Trade{doomsdayStable0, doomsdayStable1, doomsdayStable2},
 				},
 			},
 		},
diff --git a/x/protorev/keeper/msg_server_test.go b/x/protorev/keeper/msg_server_test.go
index 4efeeb03e..b463c4c43 100644
--- a/x/protorev/keeper/msg_server_test.go
+++ b/x/protorev/keeper/msg_server_test.go
@@ -16,32 +16,32 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 	testCases := []struct {
 		description       string
 		admin             string
-		hotRoutes         []*types.TokenPairArbRoutes
+		hotRoutes         []types.TokenPairArbRoutes
 		passValidateBasic bool
 		pass              bool
 	}{
 		{
 			"Invalid message (invalid admin)",
 			"admin",
-			[]*types.TokenPairArbRoutes{},
+			[]types.TokenPairArbRoutes{},
 			false,
 			false,
 		},
 		{
 			"Invalid message (mismatch admin)",
 			apptesting.CreateRandomAccounts(1)[0].String(),
-			[]*types.TokenPairArbRoutes{},
+			[]types.TokenPairArbRoutes{},
 			true,
 			false,
 		},
 		{
 			"Valid message (with proper hot routes)",
 			suite.adminAccount.String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -58,7 +58,7 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -71,11 +71,11 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 		{
 			"Invalid message (with duplicate hot routes)",
 			suite.adminAccount.String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -92,16 +92,16 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
 					TokenOut: "Juno",
 				},
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -118,7 +118,7 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -131,11 +131,11 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 		{
 			"Invalid message (with proper hot routes)",
 			suite.adminAccount.String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -152,7 +152,7 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &invalidStepSize,
+							StepSize: invalidStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -165,11 +165,11 @@ func (suite *KeeperTestSuite) TestMsgSetHotRoutes() {
 		{
 			"Invalid message with nil step size (with proper hot routes)",
 			suite.adminAccount.String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -525,7 +525,7 @@ func (suite *KeeperTestSuite) TestMsgSetPoolWeights() {
 
 	for _, testCase := range cases {
 		suite.Run(testCase.description, func() {
-			msg := types.NewMsgSetPoolWeights(testCase.admin, &testCase.poolWeights)
+			msg := types.NewMsgSetPoolWeights(testCase.admin, testCase.poolWeights)
 
 			err := msg.ValidateBasic()
 			if testCase.passValidateBasic {
@@ -544,7 +544,7 @@ func (suite *KeeperTestSuite) TestMsgSetPoolWeights() {
 
 				poolWeights := suite.App.AppKeepers.ProtoRevKeeper.GetPoolWeights(suite.Ctx)
 				suite.Require().NoError(err)
-				suite.Require().Equal(testCase.poolWeights, *poolWeights)
+				suite.Require().Equal(testCase.poolWeights, poolWeights)
 			} else {
 				suite.Require().Error(err)
 			}
@@ -557,14 +557,14 @@ func (suite *KeeperTestSuite) TestMsgSetBaseDenoms() {
 	cases := []struct {
 		description       string
 		admin             string
-		baseDenoms        []*types.BaseDenom
+		baseDenoms        []types.BaseDenom
 		passValidateBasic bool
 		pass              bool
 	}{
 		{
 			"Invalid message (invalid admin)",
 			"admin",
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1_000_000),
@@ -576,7 +576,7 @@ func (suite *KeeperTestSuite) TestMsgSetBaseDenoms() {
 		{
 			"Invalid message (invalid base denoms must start with osmo)",
 			suite.adminAccount.String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    "Atom",
 					StepSize: sdk.NewInt(1_000_000),
@@ -588,7 +588,7 @@ func (suite *KeeperTestSuite) TestMsgSetBaseDenoms() {
 		{
 			"Invalid message (invalid step size)",
 			suite.adminAccount.String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(0),
@@ -600,7 +600,7 @@ func (suite *KeeperTestSuite) TestMsgSetBaseDenoms() {
 		{
 			"Invalid message (wrong admin)",
 			apptesting.CreateRandomAccounts(1)[0].String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1_000_000),
@@ -612,7 +612,7 @@ func (suite *KeeperTestSuite) TestMsgSetBaseDenoms() {
 		{
 			"Valid message (correct admin)",
 			suite.adminAccount.String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1_000_000),
diff --git a/x/protorev/keeper/posthandler_test.go b/x/protorev/keeper/posthandler_test.go
index 8de09ad76..1e07cd1be 100644
--- a/x/protorev/keeper/posthandler_test.go
+++ b/x/protorev/keeper/posthandler_test.go
@@ -80,7 +80,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 		isCheckTx           bool
 		baseDenomGas        bool
 		expectedNumOfTrades sdk.Int
-		expectedProfits     []*sdk.Coin
+		expectedProfits     []sdk.Coin
 		expectedPoolPoints  uint64
 	}
 
@@ -107,7 +107,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.ZeroInt(),
-				expectedProfits:     []*sdk.Coin{},
+				expectedProfits:     []sdk.Coin{},
 				expectedPoolPoints:  0,
 			},
 			expectPass: true,
@@ -134,7 +134,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.ZeroInt(),
-				expectedProfits:     []*sdk.Coin{},
+				expectedProfits:     []sdk.Coin{},
 				expectedPoolPoints:  0,
 			},
 			expectPass: true,
@@ -161,7 +161,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.OneInt(),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  types.OsmosisDenomination,
 						Amount: sdk.NewInt(24848),
@@ -193,7 +193,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(2),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(5826),
@@ -229,7 +229,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(3),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(5826),
@@ -265,7 +265,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(4),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(15_767_231),
@@ -301,7 +301,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(5),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(15_767_231),
@@ -341,7 +341,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(5),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(15_767_231),
@@ -381,7 +381,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(5),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(15_767_231),
@@ -421,7 +421,7 @@ func (suite *KeeperTestSuite) TestAnteHandle() {
 				isCheckTx:           false,
 				baseDenomGas:        true,
 				expectedNumOfTrades: sdk.NewInt(5),
-				expectedProfits: []*sdk.Coin{
+				expectedProfits: []sdk.Coin{
 					{
 						Denom:  "Atom",
 						Amount: sdk.NewInt(15_767_231),
diff --git a/x/protorev/keeper/proposal_test.go b/x/protorev/keeper/proposal_test.go
index 3dea0e88a..5a926fdad 100644
--- a/x/protorev/keeper/proposal_test.go
+++ b/x/protorev/keeper/proposal_test.go
@@ -9,13 +9,12 @@ import (
 // TestSetProtoRevAdminAccount tests that the admin account can be set through a proposal
 func (suite *KeeperTestSuite) TestSetProtoRevAdminAccount() {
 	// Should be initialized to begin with
-	account, err := suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
-	suite.Require().NoError(err)
+	account := suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
 	suite.Require().Equal(account, suite.adminAccount)
 
 	// Set a new admin
 	newAdmin := apptesting.CreateRandomAccounts(1)[0]
-	err = protorev.HandleSetProtoRevAdminAccount(suite.Ctx, *suite.App.ProtoRevKeeper, &types.SetProtoRevAdminAccountProposal{
+	err := protorev.HandleSetProtoRevAdminAccount(suite.Ctx, *suite.App.ProtoRevKeeper, &types.SetProtoRevAdminAccountProposal{
 		Title:       "Updating the protorev admin account",
 		Description: "This proposal is to update the protorev admin account",
 		Account:     newAdmin.String(),
@@ -23,8 +22,7 @@ func (suite *KeeperTestSuite) TestSetProtoRevAdminAccount() {
 	suite.Require().NoError(err)
 
 	// Check that the admin account was updated
-	account, err = suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
-	suite.Require().NoError(err)
+	account = suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
 	suite.Require().Equal(newAdmin, account)
 
 	// Attempt to set a new admin with an invalid address
@@ -39,12 +37,11 @@ func (suite *KeeperTestSuite) TestSetProtoRevAdminAccount() {
 // TestSetProtoRevEnabledProposal tests that the enabled status can be set through a proposal
 func (suite *KeeperTestSuite) TestSetProtoRevEnabledProposal() {
 	// Should be enabled by default
-	enabled, err := suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
-	suite.Require().NoError(err)
+	enabled := suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
 	suite.Require().True(enabled)
 
 	// Disable the protocol
-	err = protorev.HandleEnabledProposal(suite.Ctx, *suite.App.ProtoRevKeeper, &types.SetProtoRevEnabledProposal{
+	err := protorev.HandleEnabledProposal(suite.Ctx, *suite.App.ProtoRevKeeper, &types.SetProtoRevEnabledProposal{
 		Title:       "Updating the protorev enabled status",
 		Description: "This proposal is to update the protorev enabled status",
 		Enabled:     false,
@@ -52,7 +49,6 @@ func (suite *KeeperTestSuite) TestSetProtoRevEnabledProposal() {
 	suite.Require().NoError(err)
 
 	// Check that the enabled status was updated
-	enabled, err = suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
-	suite.Require().NoError(err)
+	enabled = suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
 	suite.Require().False(enabled)
 }
diff --git a/x/protorev/keeper/protorev_test.go b/x/protorev/keeper/protorev_test.go
index 5fbae5874..37826692c 100644
--- a/x/protorev/keeper/protorev_test.go
+++ b/x/protorev/keeper/protorev_test.go
@@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestGetAllBaseDenoms() {
 	suite.Require().Equal(0, len(baseDenoms))
 
 	// Should be able to set the base denoms
-	suite.App.ProtoRevKeeper.SetBaseDenoms(suite.Ctx, []*types.BaseDenom{{Denom: "osmo"}, {Denom: "atom"}, {Denom: "weth"}})
+	suite.App.ProtoRevKeeper.SetBaseDenoms(suite.Ctx, []types.BaseDenom{{Denom: "osmo"}, {Denom: "atom"}, {Denom: "weth"}})
 	baseDenoms, err = suite.App.ProtoRevKeeper.GetAllBaseDenoms(suite.Ctx)
 	suite.Require().NoError(err)
 	suite.Require().Equal(3, len(baseDenoms))
@@ -191,28 +191,24 @@ func (suite *KeeperTestSuite) TestDeleteDeveloperFees() {
 // TestGetProtoRevEnabled tests the GetProtoRevEnabled and SetProtoRevEnabled functions.
 func (suite *KeeperTestSuite) TestGetProtoRevEnabled() {
 	// Should be initialized to true on genesis
-	protoRevEnabled, err := suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
-	suite.Require().NoError(err)
+	protoRevEnabled := suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
 	suite.Require().Equal(true, protoRevEnabled)
 
 	// Should be able to set the protoRevEnabled
 	suite.App.ProtoRevKeeper.SetProtoRevEnabled(suite.Ctx, false)
-	protoRevEnabled, err = suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
-	suite.Require().NoError(err)
+	protoRevEnabled = suite.App.ProtoRevKeeper.GetProtoRevEnabled(suite.Ctx)
 	suite.Require().Equal(false, protoRevEnabled)
 }
 
 // TestGetAdminAccount tests the GetAdminAccount and SetAdminAccount functions.
 func (suite *KeeperTestSuite) TestGetAdminAccount() {
 	// Should be initialized (look at keeper_test.go)
-	adminAccount, err := suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
-	suite.Require().NoError(err)
+	adminAccount := suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
 	suite.Require().Equal(suite.adminAccount, adminAccount)
 
 	// Should be able to set the admin account
 	suite.App.ProtoRevKeeper.SetAdminAccount(suite.Ctx, suite.TestAccs[0])
-	adminAccount, err = suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
-	suite.Require().NoError(err)
+	adminAccount = suite.App.ProtoRevKeeper.GetAdminAccount(suite.Ctx)
 	suite.Require().Equal(suite.TestAccs[0], adminAccount)
 }
 
@@ -309,7 +305,7 @@ func (suite *KeeperTestSuite) TestGetMaxPointsPerBlock() {
 func (suite *KeeperTestSuite) TestGetPoolWeights() {
 	// Should be initialized on genesis
 	poolWeights := suite.App.ProtoRevKeeper.GetPoolWeights(suite.Ctx)
-	suite.Require().Equal(types.PoolWeights{StableWeight: 5, BalancerWeight: 2, ConcentratedWeight: 2}, *poolWeights)
+	suite.Require().Equal(types.PoolWeights{StableWeight: 5, BalancerWeight: 2, ConcentratedWeight: 2}, poolWeights)
 
 	// Should be able to set the PoolWeights
 	newRouteWeights := types.PoolWeights{
@@ -321,5 +317,5 @@ func (suite *KeeperTestSuite) TestGetPoolWeights() {
 	suite.App.ProtoRevKeeper.SetPoolWeights(suite.Ctx, newRouteWeights)
 
 	poolWeights = suite.App.ProtoRevKeeper.GetPoolWeights(suite.Ctx)
-	suite.Require().Equal(newRouteWeights, *poolWeights)
+	suite.Require().Equal(newRouteWeights, poolWeights)
 }
diff --git a/x/protorev/keeper/rebalance_test.go b/x/protorev/keeper/rebalance_test.go
index 02c65d4b9..0dc6faaf2 100644
--- a/x/protorev/keeper/rebalance_test.go
+++ b/x/protorev/keeper/rebalance_test.go
@@ -506,8 +506,10 @@ func (suite *KeeperTestSuite) TestIterateRoutes() {
 					StepSize:   sdk.NewInt(1_000_000),
 				}
 			}
+			// Set a high default pool points so that all routes are considered
+			remainingPoolPoints := uint64(40)
 
-			maxProfitInputCoin, maxProfitAmount, optimalRoute := suite.App.ProtoRevKeeper.IterateRoutes(suite.Ctx, routes)
+			maxProfitInputCoin, maxProfitAmount, optimalRoute := suite.App.ProtoRevKeeper.IterateRoutes(suite.Ctx, routes, &remainingPoolPoints)
 			if test.expectPass {
 				suite.Require().Equal(test.params.expectedMaxProfitAmount, maxProfitAmount)
 				suite.Require().Equal(test.params.expectedMaxProfitInputCoin, maxProfitInputCoin)
diff --git a/x/protorev/keeper/routes_test.go b/x/protorev/keeper/routes_test.go
index 9182e7138..53df0bf75 100644
--- a/x/protorev/keeper/routes_test.go
+++ b/x/protorev/keeper/routes_test.go
@@ -209,7 +209,7 @@ func (suite *KeeperTestSuite) TestBuildHighestLiquidityRoute() {
 				Denom:    tc.swapDenom,
 				StepSize: sdk.NewInt(1_000_000),
 			}
-			routeMetaData, err := suite.App.ProtoRevKeeper.BuildHighestLiquidityRoute(suite.Ctx, &baseDenom, tc.swapIn, tc.swapOut, tc.poolId)
+			routeMetaData, err := suite.App.ProtoRevKeeper.BuildHighestLiquidityRoute(suite.Ctx, baseDenom, tc.swapIn, tc.swapOut, tc.poolId)
 
 			if tc.hasRoute {
 				suite.Require().NoError(err)
diff --git a/x/protorev/keeper/statistics_test.go b/x/protorev/keeper/statistics_test.go
index 1cc537b8b..7a52b65c1 100644
--- a/x/protorev/keeper/statistics_test.go
+++ b/x/protorev/keeper/statistics_test.go
@@ -51,7 +51,7 @@ func (suite *KeeperTestSuite) TestGetProfitsByDenom() {
 
 	// Check the result of GetAllProfits
 	allProfits := suite.App.ProtoRevKeeper.GetAllProfits(suite.Ctx)
-	suite.Require().Equal([]*sdk.Coin{{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(14000)}}, allProfits)
+	suite.Require().Equal([]sdk.Coin{{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(14000)}}, allProfits)
 
 	// Pseudo execute a third trade in a different denom
 	err = suite.App.ProtoRevKeeper.UpdateProfitsByDenom(suite.Ctx, "Atom", sdk.NewInt(1000))
@@ -59,7 +59,7 @@ func (suite *KeeperTestSuite) TestGetProfitsByDenom() {
 
 	// Check the result of GetAllProfits
 	allProfits = suite.App.ProtoRevKeeper.GetAllProfits(suite.Ctx)
-	suite.Require().Equal([]*sdk.Coin{{Denom: "Atom", Amount: sdk.NewInt(1000)}, {Denom: types.OsmosisDenomination, Amount: sdk.NewInt(14000)}}, allProfits)
+	suite.Require().Equal([]sdk.Coin{{Denom: "Atom", Amount: sdk.NewInt(1000)}, {Denom: types.OsmosisDenomination, Amount: sdk.NewInt(14000)}}, allProfits)
 }
 
 // TestGetTradesByRoute tests GetTradesByRoute, IncrementTradesByRoute, and GetAllRoutes
@@ -110,7 +110,7 @@ func (suite *KeeperTestSuite) TestGetTradesByRoute() {
 func (suite *KeeperTestSuite) TestGetProfitsByRoute() {
 	// There should be no profits that have been executed by default
 	profits := suite.App.ProtoRevKeeper.GetAllProfitsByRoute(suite.Ctx, []uint64{1, 2, 3})
-	suite.Require().Equal([]*sdk.Coin{}, profits)
+	suite.Require().Equal([]sdk.Coin{}, profits)
 
 	// Check the profits for a route that has not been executed
 	profit, err := suite.App.ProtoRevKeeper.GetProfitsByRoute(suite.Ctx, []uint64{1, 2, 3}, types.OsmosisDenomination)
@@ -128,7 +128,7 @@ func (suite *KeeperTestSuite) TestGetProfitsByRoute() {
 
 	// Check the result of GetAllProfitsByRoute
 	profits = suite.App.ProtoRevKeeper.GetAllProfitsByRoute(suite.Ctx, []uint64{1, 2, 3})
-	suite.Require().Equal([]*sdk.Coin{{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(1000)}}, profits)
+	suite.Require().Equal([]sdk.Coin{{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(1000)}}, profits)
 
 	// Pseudo execute a second trade
 	err = suite.App.ProtoRevKeeper.UpdateProfitsByRoute(suite.Ctx, []uint64{1, 2, 3}, "Atom", sdk.NewInt(2000))
@@ -141,8 +141,8 @@ func (suite *KeeperTestSuite) TestGetProfitsByRoute() {
 
 	// Check the result of GetAllProfitsByRoute
 	profits = suite.App.ProtoRevKeeper.GetAllProfitsByRoute(suite.Ctx, []uint64{1, 2, 3})
-	suite.Require().Contains(profits, &sdk.Coin{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(1000)})
-	suite.Require().Contains(profits, &sdk.Coin{Denom: "Atom", Amount: sdk.NewInt(2000)})
+	suite.Require().Contains(profits, sdk.Coin{Denom: types.OsmosisDenomination, Amount: sdk.NewInt(1000)})
+	suite.Require().Contains(profits, sdk.Coin{Denom: "Atom", Amount: sdk.NewInt(2000)})
 }
 
 // TestUpdateStatistics tests UpdateStatistics which is a wrapper for much of the statistics keeper
diff --git a/x/protorev/types/genesis_test.go b/x/protorev/types/genesis_test.go
index ff9e0a6f2..2275495fe 100644
--- a/x/protorev/types/genesis_test.go
+++ b/x/protorev/types/genesis_test.go
@@ -16,10 +16,8 @@ func TestGenesisStateValidate(t *testing.T) {
 	}{
 		{
 			description: "Default parameters with no routes",
-			genState: &types.GenesisState{
-				Params: types.DefaultParams(),
-			},
-			valid: true,
+			genState:    types.DefaultGenesis(),
+			valid:       true,
 		},
 	}
 
diff --git a/x/protorev/types/msg_test.go b/x/protorev/types/msg_test.go
index 18fc6f330..8f9e7204a 100644
--- a/x/protorev/types/msg_test.go
+++ b/x/protorev/types/msg_test.go
@@ -16,19 +16,19 @@ func TestMsgSetHotRoutes(t *testing.T) {
 	cases := []struct {
 		description string
 		admin       string
-		hotRoutes   []*types.TokenPairArbRoutes
+		hotRoutes   []types.TokenPairArbRoutes
 		pass        bool
 	}{
 		{
 			"Invalid message (invalid admin)",
 			"admin",
-			[]*types.TokenPairArbRoutes{},
+			[]types.TokenPairArbRoutes{},
 			false,
 		},
 		{
 			"Valid message (no arb routes)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{},
+			[]types.TokenPairArbRoutes{},
 			true,
 		},
 		{
@@ -37,20 +37,14 @@ func TestMsgSetHotRoutes(t *testing.T) {
 			nil,
 			false,
 		},
-		{
-			"Invalid message (nil arb route)",
-			createAccount().String(),
-			[]*types.TokenPairArbRoutes{nil},
-			false,
-		},
 		{
 			"Valid message (with arb routes)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -67,7 +61,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -79,11 +73,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (mismatched arb denoms)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -100,7 +94,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "eth",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -112,11 +106,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (with duplicate arb routes)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -133,16 +127,16 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
 					TokenOut: "Juno",
 				},
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -159,7 +153,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -171,11 +165,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (with missing trade)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -187,7 +181,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -199,18 +193,18 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (with invalid route length)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     3,
 									TokenIn:  types.OsmosisDenomination,
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -222,11 +216,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Valid message (with multiple routes)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     1,
 									TokenIn:  "Atom",
@@ -243,10 +237,10 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Atom",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     0,
 									TokenIn:  "Juno",
@@ -258,7 +252,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: "Juno",
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  types.OsmosisDenomination,
@@ -270,11 +264,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (with invalid route hops)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     3,
 									TokenIn:  types.OsmosisDenomination,
@@ -291,7 +285,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: types.OsmosisDenomination,
 								},
 							},
-							StepSize: &validStepSize,
+							StepSize: validStepSize,
 						},
 					},
 					TokenIn:  "Atom",
@@ -303,11 +297,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (unset step size)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     3,
 									TokenIn:  types.OsmosisDenomination,
@@ -335,11 +329,11 @@ func TestMsgSetHotRoutes(t *testing.T) {
 		{
 			"Invalid message (invalid step size)",
 			createAccount().String(),
-			[]*types.TokenPairArbRoutes{
+			[]types.TokenPairArbRoutes{
 				{
-					ArbRoutes: []*types.Route{
+					ArbRoutes: []types.Route{
 						{
-							Trades: []*types.Trade{
+							Trades: []types.Trade{
 								{
 									Pool:     3,
 									TokenIn:  types.OsmosisDenomination,
@@ -356,7 +350,7 @@ func TestMsgSetHotRoutes(t *testing.T) {
 									TokenOut: types.OsmosisDenomination,
 								},
 							},
-							StepSize: &invalidStepSize,
+							StepSize: invalidStepSize,
 						},
 					},
 					TokenIn:  "Atom",
@@ -553,7 +547,7 @@ func TestMsgSetPoolWeights(t *testing.T) {
 
 	for _, tc := range cases {
 		t.Run(tc.description, func(t *testing.T) {
-			msg := types.NewMsgSetPoolWeights(tc.admin, &tc.poolWeights)
+			msg := types.NewMsgSetPoolWeights(tc.admin, tc.poolWeights)
 			err := msg.ValidateBasic()
 			if tc.pass {
 				require.NoError(t, err)
@@ -568,19 +562,19 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 	cases := []struct {
 		description string
 		admin       string
-		baseDenoms  []*types.BaseDenom
+		baseDenoms  []types.BaseDenom
 		pass        bool
 	}{
 		{
 			"Invalid message (invalid admin)",
 			"admin",
-			[]*types.BaseDenom{},
+			[]types.BaseDenom{},
 			false,
 		},
 		{
 			"Invalid message (empty base denoms)",
 			createAccount().String(),
-			[]*types.BaseDenom{},
+			[]types.BaseDenom{},
 			false,
 		},
 		{
@@ -589,16 +583,10 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 			nil,
 			false,
 		},
-		{
-			"Invalid message (nil base denoms)",
-			createAccount().String(),
-			[]*types.BaseDenom{{Denom: types.OsmosisDenomination, StepSize: sdk.NewInt(100)}, nil},
-			false,
-		},
 		{
 			"Invalid message (base denoms does not start with osmosis)",
 			createAccount().String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    "Atom",
 					StepSize: sdk.NewInt(10),
@@ -609,7 +597,7 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 		{
 			"Invalid message (invalid step size)",
 			createAccount().String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(0),
@@ -620,7 +608,7 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 		{
 			"Invalid message (duplicate base denoms)",
 			createAccount().String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1),
@@ -635,7 +623,7 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 		{
 			"Valid message (single denom)",
 			createAccount().String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1),
@@ -646,7 +634,7 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 		{
 			"Valid message (multiple denoms)",
 			createAccount().String(),
-			[]*types.BaseDenom{
+			[]types.BaseDenom{
 				{
 					Denom:    types.OsmosisDenomination,
 					StepSize: sdk.NewInt(1),
@@ -662,6 +650,24 @@ func TestMsgSetBaseDenoms(t *testing.T) {
 			},
 			true,
 		},
+		{
+			"Invalid message (multiple denoms with a single unset denom)",
+			createAccount().String(),
+			[]types.BaseDenom{
+				{
+					Denom:    types.OsmosisDenomination,
+					StepSize: sdk.NewInt(1),
+				},
+				{
+					Denom:    "Atom",
+					StepSize: sdk.NewInt(1),
+				},
+				{
+					Denom: "testDenom",
+				},
+			},
+			false,
+		},
 	}
 
 	for _, tc := range cases {