Repository: desmos-labs/desmos
Pull request #1066 (2023-01-10 15:41:33)

docs: fix typos
Fix: typos


Patch:
diff --git a/.changeset/entries/43407cab0ad8588c2ad460e3263a18402e65f441fdd5abe33d7c1be740faf0df.yaml b/.changeset/entries/43407cab0ad8588c2ad460e3263a18402e65f441fdd5abe33d7c1be740faf0df.yaml
new file mode 100644
index 00000000..aceb7678
--- /dev/null
+++ b/.changeset/entries/43407cab0ad8588c2ad460e3263a18402e65f441fdd5abe33d7c1be740faf0df.yaml
@@ -0,0 +1,6 @@
+type: ci
+module: other
+pull_request: 1061
+description: Added mutation testing
+backward_compatible: true
+date: 2023-01-04T05:13:54.9256337Z
diff --git a/.github/workflows/build-docs-preview.yaml b/.github/workflows/build-docs-preview.yaml
index 35dfbcfd..c56553eb 100644
--- a/.github/workflows/build-docs-preview.yaml
+++ b/.github/workflows/build-docs-preview.yaml
@@ -43,9 +43,10 @@ jobs:
           NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
           NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
 
-      - name: Write preview url
+      - name: Comment preview URL 🗨️
+        if: env.GIT_DIFF
         uses: thollander/actions-comment-pull-request@v2
         with:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           message: '👀 Docs preview available here: ${{ steps.deploy-preview.outputs.deploy-url }}'
-          comment_includes: '👀 Docs preview available here: '
+          comment_tag: '👀 Docs preview available here: '
diff --git a/Makefile b/Makefile
index aea0c71e..0c0d5369 100644
--- a/Makefile
+++ b/Makefile
@@ -290,6 +290,10 @@ benchmark:
 	@test -e bench-master.txt && benchstat bench-master.txt bench-$(REF_NAME).txt || benchstat bench-$(REF_NAME).txt
 .PHONY: benchmark
 
+test-mutation:
+	@bash scripts/mutation-test.sh $(MODULES)
+.PHONY: test-mutation
+
 ###############################################################################
 ###                                Linting                                  ###
 ###############################################################################
diff --git a/docs/docs/02-developers/01-overview.md b/docs/docs/02-developers/01-overview.md
index 694f9ca6..3848c640 100644
--- a/docs/docs/02-developers/01-overview.md
+++ b/docs/docs/02-developers/01-overview.md
@@ -14,7 +14,7 @@ If you want to know more about the base concepts of a blockchain and understand
 ## Core features
 The core features of Desmos are organised in **modules** following the specification of the [Cosmos-SDK](https://docs.cosmos.network/main/building-modules/intro.html).   
 
-Here a brief description of each one of these:
+Here is a brief description of each one of these:
 
 * `Profiles`: Handles the creation and management of a decentralized identity and its own links with both your other chains wallets and centralised applications;
 
@@ -35,4 +35,4 @@ external services.
 * `Fees`: Allows setting custom additional fees to modules' messages;
 * `Supply`: Allows retrieving information about a particular token total and circulating supply.
 
-If you want to know more about each module, its concepts and how to interact with them check the [modules] section.
\ No newline at end of file
+If you want to know more about each module, its concepts and how to interact with them check the [modules] section.
diff --git a/docs/docs/02-developers/03-tools-to-build.md b/docs/docs/02-developers/03-tools-to-build.md
index 7dc96714..4c7092d1 100644
--- a/docs/docs/02-developers/03-tools-to-build.md
+++ b/docs/docs/02-developers/03-tools-to-build.md
@@ -11,7 +11,7 @@ In order to let developers easily interact with the Desmos blockchain, we have d
 ## DesmJS
 
 To make it easy to develop dApps on the top of the Desmos chain we have built a `typescript` framework called **DesmJS**. 
-DesmJS is based on to the analog framework for Cosmos based chains [CosmJS](https://github.com/cosmos/cosmjs) but focused on Desmos. 
+DesmJS is based on the analog framework for Cosmos based chains [CosmJS](https://github.com/cosmos/cosmjs) but focused on Desmos. 
 DesmJS contains 3 different packages, each one with a specific scope:
 1. The [@desmoslabs/desmjs](https://www.npmjs.com/package/@desmoslabs/desmjs) package contains the client that allows to easily create, sign and broadcast transactions containing Desmos (and Cosmos) messages;
 2. The [@desmoslabs/desmjs-types](https://www.npmjs.com/package/@desmoslabs/desmjs-types) package contains the Desmos types protobuf definitions;
@@ -283,4 +283,4 @@ query QueryUserPosts {
     ]
   }
 }
-```
\ No newline at end of file
+```
diff --git a/docs/docs/02-developers/04-query-data.md b/docs/docs/02-developers/04-query-data.md
index 317d0cee..886d221c 100644
--- a/docs/docs/02-developers/04-query-data.md
+++ b/docs/docs/02-developers/04-query-data.md
@@ -61,7 +61,7 @@ The above endpoints can be used with the following endpoints to get the desired
 * [Fees REST endpoints](02-modules/fees/06-client.md#rest).
 
 ## GQL
-Another way to query the Desmos data is GQL. GQL is different from the above methods because it offers high possibilities of customisation for developers based on their needs. It is possible to interact with GQL endpoints in the client you are building by using one of the many libraries available for this kind of interaction. You can check what suites your needs here: [GraphQL resources](https://graphql.org/code/).
+Another way to query the Desmos data is GQL. GQL is different from the above methods because it offers high possibilities of customisation for developers based on their needs. It is possible to interact with GQL endpoints in the client you are building by using one of the many libraries available for this kind of interaction. You can check what suits your needs here: [GraphQL resources](https://graphql.org/code/).
 
 The GQL endpoints for Desmos chains are the following:
 1. [Testnet GQL endpoint](../05-testnet/05-endpoints.md#gql)
diff --git a/docs/docs/02-developers/07-faq.md b/docs/docs/02-developers/07-faq.md
index 7b2010e7..2db5efd9 100644
--- a/docs/docs/02-developers/07-faq.md
+++ b/docs/docs/02-developers/07-faq.md
@@ -32,7 +32,7 @@ Sending a transaction is pretty straight forward. All what you need to have is a
 Please note that when sending transactions you are required to pay a **fee** so that the chain can sustain economically. To avoid paying a higher fee and wasting the user's funds, you should always **put multiple messages inside the same transactions**. This will also decrease the overall execution of all messages and can allow you to save time and provide the users a better UX overall. 
 
 ### How long does transactions take to be executed? 
-Unluckily there is no way to know how long a transaction will take before being executed. The time that passes between it being received by a full node and it's actual execution and verification can vary a lot based on how many messages are inside, how complex each operation to perform is as well as how high the paid fees are. 
+Unluckily there is no way to know how long a transaction will take before being executed. The time that passes between it being received by a full node and its actual execution and verification can vary a lot based on how many messages are inside, how complex each operation to perform is as well as how high the paid fees are. 
 
 If you want you can try speeding up the transactions execution by specifying a higher fee to be paid during the execution itself, but this might now change a lot if other users are doing the same.
 
@@ -54,4 +54,4 @@ Even if you edit or delete a post, the original one will always be inside the ch
 
 For this reason, we suggest you to take **all the possible precautions** before sending any transaction to the chain. 
 
-As an example, you might not want to send a transaction for every post that the user creates, but instead store the locally created posts offline for a certain amount of time (i.e. 2 minutes) and later send the transactions. During this time, the user will still be able to delete the posts if he wants, but once synced on the chain you will no longer be able to take them down.
\ No newline at end of file
+As an example, you might not want to send a transaction for every post that the user creates, but instead store the locally created posts offline for a certain amount of time (i.e. 2 minutes) and later send the transactions. During this time, the user will still be able to delete the posts if he wants, but once synced on the chain you will no longer be able to take them down.
diff --git a/go.mod b/go.mod
index 0b39ba08..abbc78b0 100644
--- a/go.mod
+++ b/go.mod
@@ -18,6 +18,7 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0
 	github.com/manifoldco/promptui v0.9.0
 	github.com/mr-tron/base58 v1.2.0
+	github.com/osmosis-labs/go-mutesting v0.0.0-20221219192234-827e6d6b9d4e
 	github.com/prometheus/client_golang v1.14.0
 	github.com/rakyll/statik v0.1.7
 	github.com/regen-network/cosmos-proto v0.3.1
@@ -149,6 +150,7 @@ require (
 	github.com/hexops/gotextdiff v1.0.3 // indirect
 	github.com/improbable-eng/grpc-web v0.14.1 // indirect
 	github.com/inconshreveable/mousetrap v1.0.1 // indirect
+	github.com/jessevdk/go-flags v1.4.0 // indirect
 	github.com/jgautheron/goconst v1.5.1 // indirect
 	github.com/jingyugao/rowserrcheck v1.1.1 // indirect
 	github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
@@ -241,6 +243,9 @@ require (
 	github.com/uudashr/gocognit v1.0.6 // indirect
 	github.com/yagipy/maintidx v1.0.0 // indirect
 	github.com/yeya24/promlinter v0.2.0 // indirect
+	github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00 // indirect
+	github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439 // indirect
+	github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac // indirect
 	github.com/zondax/hid v0.9.0 // indirect
 	gitlab.com/bosi/decorder v0.2.3 // indirect
 	go.etcd.io/bbolt v1.3.6 // indirect
diff --git a/go.sum b/go.sum
index fcf1e728..4b95debe 100644
--- a/go.sum
+++ b/go.sum
@@ -681,6 +681,7 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH
 github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
 github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
 github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
@@ -719,6 +720,7 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E
 github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
 github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c=
 github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
@@ -821,6 +823,7 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
+github.com/mattn/goveralls v0.0.3/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
@@ -898,6 +901,7 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
 github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
@@ -922,6 +926,8 @@ 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/go-mutesting v0.0.0-20221219192234-827e6d6b9d4e h1:yuDnnXG7UYi96gOVrDpEamdx14xr772yRg/LmJYobHE=
+github.com/osmosis-labs/go-mutesting v0.0.0-20221219192234-827e6d6b9d4e/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
 github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
 github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
 github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
@@ -1222,6 +1228,12 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00 h1:KNiPkpQpqXvq40f8hh/1T7QasLJT/1MuBoOYA2vlxJk=
+github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00/go.mod h1:RJt5SMnyha63GbdwCKJiX9djvvEC4KsfXJSZ5oTmSPw=
+github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439 h1:yHqsjUkj0HWbKPw/6ZqC0/eMklaRpqubA199vaRLzzE=
+github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439/go.mod h1:G4FVqCRvfz74AEB1crDNdQuvMfOoKtk7DlePsnV2yGs=
+github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac h1:uiFRlKzyIzHeLOthe0ethUkSGW7POlqxU3Tc21R8QpQ=
+github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac/go.mod h1:wJ9WGevuM/rw8aB2pQPFMUgXZWeaouI0ueFamR0DUPE=
 github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
 github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
 gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0=
@@ -1525,6 +1537,7 @@ golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxb
 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
@@ -1546,6 +1559,7 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
diff --git a/tools/tools.go b/tools/tools.go
index 939aaabb..5506fc01 100644
--- a/tools/tools.go
+++ b/tools/tools.go
@@ -9,4 +9,5 @@ package tools
 
 import (
 	_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
+	_ "github.com/osmosis-labs/go-mutesting/cmd/go-mutesting"
 )
diff --git a/x/profiles/abci.go b/x/profiles/abci.go
index edd5647b..baf71750 100644
--- a/x/profiles/abci.go
+++ b/x/profiles/abci.go
@@ -10,7 +10,7 @@ import (
 // BeginBlocker is called every block, processes expired application links
 func BeginBlocker(ctx sdk.Context, keeper keeper.Keeper) {
 	// Iterate over all the expiring application links
-	keeper.IterateExpiringApplicationLinks(ctx, func(_ int64, link types.ApplicationLink) (stop bool) {
+	keeper.IterateExpiringApplicationLinks(ctx, func(link types.ApplicationLink) (stop bool) {
 		// Delete the application link
 		keeper.DeleteApplicationLink(ctx, link)
 		return false
diff --git a/x/profiles/keeper/alias_functions.go b/x/profiles/keeper/alias_functions.go
index a32569a4..1d6ea2fa 100644
--- a/x/profiles/keeper/alias_functions.go
+++ b/x/profiles/keeper/alias_functions.go
@@ -10,15 +10,13 @@ import (
 )
 
 // IterateProfiles iterates through the Profiles set and performs the provided function
-func (k Keeper) IterateProfiles(ctx sdk.Context, fn func(index int64, profile *types.Profile) (stop bool)) {
-	i := int64(0)
+func (k Keeper) IterateProfiles(ctx sdk.Context, fn func(profile *types.Profile) (stop bool)) {
+
 	k.ak.IterateAccounts(ctx, func(account authtypes.AccountI) (stop bool) {
 		profile, ok := account.(*types.Profile)
 
-		stop = false
 		if ok {
-			stop = fn(i, profile)
-			i++
+			stop = fn(profile)
 		}
 
 		return stop
@@ -28,7 +26,7 @@ func (k Keeper) IterateProfiles(ctx sdk.Context, fn func(index int64, profile *t
 // GetProfiles returns all the profiles that are stored inside the given context
 func (k Keeper) GetProfiles(ctx sdk.Context) []*types.Profile {
 	var profiles []*types.Profile
-	k.IterateProfiles(ctx, func(_ int64, profile *types.Profile) (stop bool) {
+	k.IterateProfiles(ctx, func(profile *types.Profile) (stop bool) {
 		profiles = append(profiles, profile)
 		return false
 	})
@@ -48,77 +46,69 @@ func (k Keeper) HasProfile(ctx sdk.Context, user string) bool {
 
 // IterateDTagTransferRequests iterates over all the DTag transfer requests and performs the provided function
 func (k Keeper) IterateDTagTransferRequests(
-	ctx sdk.Context, fn func(index int64, dTagTransferRequest types.DTagTransferRequest) (stop bool),
+	ctx sdk.Context, fn func(dTagTransferRequest types.DTagTransferRequest) (stop bool),
 ) {
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.DTagTransferRequestPrefix)
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		request := types.MustUnmarshalDTagTransferRequest(k.cdc, iterator.Value())
-		stop := fn(i, request)
+		stop := fn(request)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
 // IterateUserIncomingDTagTransferRequests iterates over all the DTag transfer request made to the given user
 // and performs the provided function
 func (k Keeper) IterateUserIncomingDTagTransferRequests(
-	ctx sdk.Context, user string, fn func(index int64, dTagTransferRequest types.DTagTransferRequest) (stop bool),
+	ctx sdk.Context, user string, fn func(dTagTransferRequest types.DTagTransferRequest) (stop bool),
 ) {
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.IncomingDTagTransferRequestsPrefix(user))
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		request := types.MustUnmarshalDTagTransferRequest(k.cdc, iterator.Value())
-		stop := fn(i, request)
+		stop := fn(request)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
 // --------------------------------------------------------------------------------------------------------------------
 
 // IterateApplicationLinks iterates through all the application links and performs the provided function
-func (k Keeper) IterateApplicationLinks(ctx sdk.Context, fn func(index int64, link types.ApplicationLink) (stop bool)) {
+func (k Keeper) IterateApplicationLinks(ctx sdk.Context, fn func(link types.ApplicationLink) (stop bool)) {
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.ApplicationLinkPrefix)
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		link := types.MustUnmarshalApplicationLink(k.cdc, iterator.Value())
-		stop := fn(i, link)
+		stop := fn(link)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
 // IterateUserApplicationLinks iterates through all the application links related to the given user
 // and performs the provided function
-func (k Keeper) IterateUserApplicationLinks(ctx sdk.Context, user string, fn func(index int64, link types.ApplicationLink) (stop bool)) {
+func (k Keeper) IterateUserApplicationLinks(ctx sdk.Context, user string, fn func(link types.ApplicationLink) (stop bool)) {
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.UserApplicationLinksPrefix(user))
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		link := types.MustUnmarshalApplicationLink(k.cdc, iterator.Value())
-		stop := fn(i, link)
+		stop := fn(link)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
@@ -126,7 +116,7 @@ func (k Keeper) IterateUserApplicationLinks(ctx sdk.Context, user string, fn fun
 // applications links entries stored inside the current context
 func (k Keeper) GetApplicationLinks(ctx sdk.Context) []types.ApplicationLink {
 	var links []types.ApplicationLink
-	k.IterateApplicationLinks(ctx, func(index int64, link types.ApplicationLink) (stop bool) {
+	k.IterateApplicationLinks(ctx, func(link types.ApplicationLink) (stop bool) {
 		links = append(links, link)
 		return false
 	})
@@ -135,13 +125,12 @@ func (k Keeper) GetApplicationLinks(ctx sdk.Context) []types.ApplicationLink {
 
 // IterateExpiringApplicationLinks iterates through all the expiring application links references.
 // The key will be skipped and deleted if the application link has already been deleted.
-func (k Keeper) IterateExpiringApplicationLinks(ctx sdk.Context, fn func(index int64, link types.ApplicationLink) (stop bool)) {
+func (k Keeper) IterateExpiringApplicationLinks(ctx sdk.Context, fn func(link types.ApplicationLink) (stop bool)) {
 	store := ctx.KVStore(k.storeKey)
 
 	iterator := sdk.KVStorePrefixIterator(store, types.ExpiringAppLinkTimePrefix)
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		// This iterator has the following key and value structure:
 		// ExpiringAppLinkTimePrefix | Expiration Time | Client ID ->  Client ID
@@ -172,50 +161,45 @@ func (k Keeper) IterateExpiringApplicationLinks(ctx sdk.Context, fn func(index i
 		if ctx.BlockTime().After(expiringTime) {
 			applicationKey := store.Get(clientIDKey)
 			link := types.MustUnmarshalApplicationLink(k.cdc, store.Get(applicationKey))
-			stop := fn(i, link)
+			stop := fn(link)
 			if stop {
 				break
 			}
 		}
-		i++
 	}
 }
 
 // --------------------------------------------------------------------------------------------------------------------
 
 // IterateChainLinks iterates through the chain links and perform the provided function
-func (k Keeper) IterateChainLinks(ctx sdk.Context, fn func(index int64, link types.ChainLink) (stop bool)) {
+func (k Keeper) IterateChainLinks(ctx sdk.Context, fn func(link types.ChainLink) (stop bool)) {
 	store := ctx.KVStore(k.storeKey)
 	iterator := sdk.KVStorePrefixIterator(store, types.ChainLinksPrefix)
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		link := types.MustUnmarshalChainLink(k.cdc, iterator.Value())
-		stop := fn(i, link)
+		stop := fn(link)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
 // IterateUserChainLinks iterates through all the chain links related to the given user and perform the provided function
-func (k Keeper) IterateUserChainLinks(ctx sdk.Context, user string, fn func(index int64, link types.ChainLink) (stop bool)) {
+func (k Keeper) IterateUserChainLinks(ctx sdk.Context, user string, fn func(link types.ChainLink) (stop bool)) {
 	store := ctx.KVStore(k.storeKey)
 
 	iterator := sdk.KVStorePrefixIterator(store, types.UserChainLinksPrefix(user))
 	defer iterator.Close()
 
-	i := int64(0)
 	for ; iterator.Valid(); iterator.Next() {
 		link := types.MustUnmarshalChainLink(k.cdc, iterator.Value())
 
-		stop := fn(i, link)
+		stop := fn(link)
 		if stop {
 			break
 		}
-		i++
 	}
 }
 
@@ -239,7 +223,7 @@ func (k Keeper) IterateUserChainLinksByChain(ctx sdk.Context, user string, chain
 // GetChainLinks allows to returns the list of all stored chain links
 func (k Keeper) GetChainLinks(ctx sdk.Context) []types.ChainLink {
 	var links []types.ChainLink
-	k.IterateChainLinks(ctx, func(_ int64, link types.ChainLink) (stop bool) {
+	k.IterateChainLinks(ctx, func(link types.ChainLink) (stop bool) {
 		links = append(links, link)
 		return false
 	})
diff --git a/x/profiles/keeper/invariants.go b/x/profiles/keeper/invariants.go
index 1112ff81..67a963ae 100644
--- a/x/profiles/keeper/invariants.go
+++ b/x/profiles/keeper/invariants.go
@@ -46,7 +46,7 @@ func AllInvariants(k Keeper) sdk.Invariant {
 func ValidProfilesInvariant(k Keeper) sdk.Invariant {
 	return func(ctx sdk.Context) (string, bool) {
 		var invalidProfiles []*types.Profile
-		k.IterateProfiles(ctx, func(_ int64, profile *types.Profile) (stop bool) {
+		k.IterateProfiles(ctx, func(profile *types.Profile) (stop bool) {
 			if err := profile.Validate(); err != nil {
 				invalidProfiles = append(invalidProfiles, profile)
 			}
@@ -78,7 +78,7 @@ func formatOutputProfiles(invalidProfiles []*types.Profile) (outputProfiles stri
 func ValidDTagTransferRequests(k Keeper) sdk.Invariant {
 	return func(ctx sdk.Context) (string, bool) {
 		var invalidDTagTransferRequests []types.DTagTransferRequest
-		k.IterateDTagTransferRequests(ctx, func(index int64, request types.DTagTransferRequest) (stop bool) {
+		k.IterateDTagTransferRequests(ctx, func(request types.DTagTransferRequest) (stop bool) {
 			if !k.HasProfile(ctx, request.Receiver) || request.Sender == request.Receiver {
 				invalidDTagTransferRequests = append(invalidDTagTransferRequests, request)
 			}
@@ -109,7 +109,7 @@ func formatOutputDTagTransferRequests(requests []types.DTagTransferRequest) (out
 func ValidChainLinks(k Keeper) sdk.Invariant {
 	return func(ctx sdk.Context) (string, bool) {
 		var invalidChainLinks []types.ChainLink
-		k.IterateChainLinks(ctx, func(index int64, link types.ChainLink) (stop bool) {
+		k.IterateChainLinks(ctx, func(link types.ChainLink) (stop bool) {
 			if !k.HasProfile(ctx, link.User) {
 				invalidChainLinks = append(invalidChainLinks, link)
 			}
@@ -141,7 +141,7 @@ func formatOutputChainLinks(links []types.ChainLink) (output string) {
 func ValidApplicationLinks(k Keeper) sdk.Invariant {
 	return func(ctx sdk.Context) (string, bool) {
 		var invalidApplicationLinks []types.ApplicationLink
-		k.IterateApplicationLinks(ctx, func(index int64, link types.ApplicationLink) (stop bool) {
+		k.IterateApplicationLinks(ctx, func(link types.ApplicationLink) (stop bool) {
 			if !k.HasProfile(ctx, link.User) {
 				invalidApplicationLinks = append(invalidApplicationLinks, link)
 			}
diff --git a/x/profiles/keeper/keeper_app_links.go b/x/profiles/keeper/keeper_app_links.go
index 42e4823d..fdf38500 100644
--- a/x/profiles/keeper/keeper_app_links.go
+++ b/x/profiles/keeper/keeper_app_links.go
@@ -120,7 +120,7 @@ func (k Keeper) DeleteApplicationLink(ctx sdk.Context, appLink types.Application
 // DeleteAllUserApplicationLinks delete all the applications links associated with the given user
 func (k Keeper) DeleteAllUserApplicationLinks(ctx sdk.Context, user string) {
 	var links []types.ApplicationLink
-	k.IterateUserApplicationLinks(ctx, user, func(index int64, link types.ApplicationLink) (stop bool) {
+	k.IterateUserApplicationLinks(ctx, user, func(link types.ApplicationLink) (stop bool) {
 		links = append(links, link)
 		return false
 	})
diff --git a/x/profiles/keeper/keeper_chain_links.go b/x/profiles/keeper/keeper_chain_links.go
index 4571d924..39549c70 100644
--- a/x/profiles/keeper/keeper_chain_links.go
+++ b/x/profiles/keeper/keeper_chain_links.go
@@ -96,7 +96,7 @@ func (k Keeper) DeleteChainLink(ctx sdk.Context, link types.ChainLink) {
 // DeleteAllUserChainLinks deletes all the chain links associated with the given user
 func (k Keeper) DeleteAllUserChainLinks(ctx sdk.Context, user string) {
 	var links []types.ChainLink
-	k.IterateUserChainLinks(ctx, user, func(index int64, link types.ChainLink) (stop bool) {
+	k.IterateUserChainLinks(ctx, user, func(link types.ChainLink) (stop bool) {
 		links = append(links, link)
 		return false
 	})
diff --git a/x/profiles/keeper/keeper_dtag_transfers.go b/x/profiles/keeper/keeper_dtag_transfers.go
index 5e35e2f5..92959874 100644
--- a/x/profiles/keeper/keeper_dtag_transfers.go
+++ b/x/profiles/keeper/keeper_dtag_transfers.go
@@ -81,7 +81,7 @@ func (k Keeper) DeleteDTagTransferRequest(ctx sdk.Context, sender, recipient str
 // DeleteAllUserIncomingDTagTransferRequests deletes all the requests made to the given user
 func (k Keeper) DeleteAllUserIncomingDTagTransferRequests(ctx sdk.Context, receiver string) {
 	var requests []types.DTagTransferRequest
-	k.IterateUserIncomingDTagTransferRequests(ctx, receiver, func(index int64, request types.DTagTransferRequest) (stop bool) {
+	k.IterateUserIncomingDTagTransferRequests(ctx, receiver, func(request types.DTagTransferRequest) (stop bool) {
 		requests = append(requests, request)
 		return false
 	})


Test patch:
diff --git a/.github/workflows/mutest.yml b/.github/workflows/mutest.yml
new file mode 100644
index 00000000..86165885
--- /dev/null
+++ b/.github/workflows/mutest.yml
@@ -0,0 +1,47 @@
+name: Generate Mutation Test Errors
+
+on:
+  tags:
+    - "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
+    - "v[0-9]+.[0-9]+.[0-9]+-rc*" # Push events to matching v*, i.e. v1.0-rc1, v20.15.10-rc5
+
+jobs:
+  Test:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout 🛎️
+        uses: actions/checkout@v3
+
+      - name: Setup Go 🧰
+        uses: actions/setup-go@v3
+        with:
+          go-version: 1.18
+
+      - name: Run mutation tests 🧪
+        continue-on-error: true
+        run: make test-mutation $MODULES
+        env:
+          MODULES: fees,profiles,subspaces,relationships,posts,reports,reactions
+      
+      - name: Format output 🔍
+        id: mutest-formatted
+        run: |
+          cat mutation_test_result.txt | grep -Ev "PASS" | grep -Ev "SKIP" | tee mutation_test_result.txt
+      
+      - name: Generate code blocks 🧑‍💻
+        id: gen-code-blocks
+        run: |
+          cat mutation_test_result.txt  | sed "s# @@# @@\n\`\`\`go\n#g " | sed "s#FAIL#\`\`\`\nFAIL\n\n\n#g " > go_mutation_test_result.txt
+      
+      - name: Read output file 👀
+        id: result
+        uses: juliangruber/read-file-action@v1
+        with:
+          path: go_mutation_test_result.txt
+      
+      - name: Create issue 🚩
+        uses: dacbd/create-issue-action@main
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          title: Mutation test ${{ steps.vars.outputs.tag }}
+          body: ${{ steps.result.outputs.content }}
\ No newline at end of file
diff --git a/scripts/mutation-test.sh b/scripts/mutation-test.sh
new file mode 100644
index 00000000..fb04a8ca
--- /dev/null
+++ b/scripts/mutation-test.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+set -eo pipefail
+oIFS="$IFS"; IFS=, ; set -- $1 ; IFS="$oIFS"
+
+DISABLED_MUTATORS='branch/*'
+
+# Only consider the following:
+# * go files in types, keeper, or module root directories
+# * ignore test and Protobuf files
+# * ignore simulation test files
+# * ignore legacy files
+go_file_exclusions="-type f ! -path */client/* ! -path */simulation/* ! -path */legacy/* -name *.go -and -not -name *_test.go -and -not -name *pb* -and -not -name module.go -and -not -name ibc_module.go"
+MUTATION_SOURCES=$(find ./x  $go_file_exclusions )
+
+# Filter on a module-by-module basis as provided by input
+arg_len=$#
+
+for i in "$@"; do
+  if [ $arg_len -gt 1 ]; then
+    MODULE_FORMAT+="./x/$i\|"
+    MODULE_NAMES+="${i} "
+    let "arg_len--"
+  else
+    MODULE_FORMAT+="./x/$i"
+    MODULE_NAMES+="${i}"
+  fi
+done
+
+MUTATION_SOURCES=$(echo "$MUTATION_SOURCES" | grep "$MODULE_FORMAT")
+
+# Collect multiple lines into a single line to be fed into go-mutesting
+MUTATION_SOURCES=$(echo "$MUTATION_SOURCES" | tr '\n' ' ')
+
+echo "################################################################################"
+echo "### WARNING! This test will take hours to complete!"
+echo "################################################################################"
+
+echo "running mutation tests for the following module(s): $MODULE_NAMES"
+OUTPUT=$(go run github.com/osmosis-labs/go-mutesting/cmd/go-mutesting --disable=$DISABLED_MUTATORS $MUTATION_SOURCES | tee /dev/tty)
+
+# Fetch the final result output and the overall mutation testing score
+RESULT=$(echo "$OUTPUT" | grep 'The mutation score')
+SCORE=$(echo "$RESULT" | grep -Eo '[[:digit:]]\.[[:digit:]]+')
+
+echo "writing mutation test result to mutation_test_result.txt"
+echo "$OUTPUT" > mutation_test_result.txt
+
+# Print the mutation score breakdown
+echo $RESULT
+
+# Return a non-zero exit code if the score is below 75%
+if (( $(echo "$SCORE < 0.75" |bc -l) )); then
+  echo "Mutation testing score below desired level ($SCORE < 0.75)"
+  exit 1
+fi
\ No newline at end of file
diff --git a/x/profiles/keeper/alias_functions_test.go b/x/profiles/keeper/alias_functions_test.go
index 22cf3ce0..37644ea6 100644
--- a/x/profiles/keeper/alias_functions_test.go
+++ b/x/profiles/keeper/alias_functions_test.go
@@ -56,7 +56,7 @@ func (suite *KeeperTestSuite) TestKeeper_IterateProfile() {
 	}
 
 	var validProfiles []*types.Profile
-	suite.k.IterateProfiles(suite.ctx, func(_ int64, profile *types.Profile) (stop bool) {
+	suite.k.IterateProfiles(suite.ctx, func(profile *types.Profile) (stop bool) {
 		if profile.DTag == "not" {
 			return false
 		}
@@ -138,9 +138,9 @@ func (suite *KeeperTestSuite) TestKeeper_IterateUserIncomingDTagTransferRequests
 	}
 
 	iterations := 0
-	suite.k.IterateUserIncomingDTagTransferRequests(suite.ctx, address, func(index int64, request types.DTagTransferRequest) (stop bool) {
-		iterations += 1
-		return index == 1
+	suite.k.IterateUserIncomingDTagTransferRequests(suite.ctx, address, func(request types.DTagTransferRequest) (stop bool) {
+		iterations++
+		return iterations == 1
 	})
 	suite.Require().Equal(iterations, 2)
 }
@@ -204,9 +204,9 @@ func (suite *KeeperTestSuite) TestKeeper_IterateUserApplicationLinks() {
 	}
 
 	var iterated []types.ApplicationLink
-	suite.k.IterateUserApplicationLinks(ctx, address, func(index int64, link types.ApplicationLink) (stop bool) {
+	suite.k.IterateUserApplicationLinks(ctx, address, func(link types.ApplicationLink) (stop bool) {
 		iterated = append(iterated, link)
-		return index == 1
+		return len(iterated) == 1
 	})
 
 	suite.Require().Equal([]types.ApplicationLink{links[0], links[1]}, iterated)
@@ -349,7 +349,7 @@ func (suite *KeeperTestSuite) TestKeeper_IterateExpiringApplicationLinks() {
 			}
 
 			var iteratedLinks []types.ApplicationLink
-			suite.k.IterateExpiringApplicationLinks(ctx, func(index int64, link types.ApplicationLink) (stop bool) {
+			suite.k.IterateExpiringApplicationLinks(ctx, func(link types.ApplicationLink) (stop bool) {
 				iteratedLinks = append(iteratedLinks, link)
 				return false
 			})
diff --git a/x/profiles/keeper/keeper_chain_links_test.go b/x/profiles/keeper/keeper_chain_links_test.go
index 13188d3e..300c00fc 100644
--- a/x/profiles/keeper/keeper_chain_links_test.go
+++ b/x/profiles/keeper/keeper_chain_links_test.go
@@ -551,7 +551,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteAllUserChainLinks() {
 			check: func(ctx sdk.Context) {
 				address := "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"
 				var iterations = 0
-				suite.k.IterateUserChainLinks(ctx, address, func(index int64, link types.ChainLink) (stop bool) {
+				suite.k.IterateUserChainLinks(ctx, address, func(link types.ChainLink) (stop bool) {
 					iterations++
 					return false
 				})
@@ -601,7 +601,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteAllUserChainLinks() {
 			check: func(ctx sdk.Context) {
 				address := "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"
 				var iterations = 0
-				suite.k.IterateUserChainLinks(ctx, address, func(index int64, link types.ChainLink) (stop bool) {
+				suite.k.IterateUserChainLinks(ctx, address, func(link types.ChainLink) (stop bool) {
 					iterations++
 					return false
 				})
diff --git a/x/profiles/keeper/keeper_dtag_transfers_test.go b/x/profiles/keeper/keeper_dtag_transfers_test.go
index 246422f2..90ab2135 100644
--- a/x/profiles/keeper/keeper_dtag_transfers_test.go
+++ b/x/profiles/keeper/keeper_dtag_transfers_test.go
@@ -353,7 +353,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteAllUserIncomingDTagTransferReques
 				user := "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"
 
 				var iterations = 0
-				suite.k.IterateUserIncomingDTagTransferRequests(ctx, user, func(_ int64, _ types.DTagTransferRequest) (stop bool) {
+				suite.k.IterateUserIncomingDTagTransferRequests(ctx, user, func(_ types.DTagTransferRequest) (stop bool) {
 					iterations += 1
 					return false
 				})