diff --git a/CHANGELOG.md b/CHANGELOG.md
index f01665b..03f3cf5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - **BREAKING** Formulas, which can be used to calculate buy max for you
     - Requirements can use them so repeatables and challenges can be "buy max" without any extra effort
     - Conversions now use formulas instead of the old scaling functions system, allowing for arbitrary functions that are much easier to follow
-    - There's a utility for converting modifiers to formulas, thus replacing things like the gain modifier on conversions
+    - Modifiers have a new getFormula property
 - Action feature, which is a clickable with a cooldown
 - ETA util (calculates time until a specific amount of a resource, based on its current gain rate)
 - createCollapsibleAchievements util
diff --git a/src/data/common.tsx b/src/data/common.tsx
index 3246135..8050818 100644
--- a/src/data/common.tsx
+++ b/src/data/common.tsx
@@ -491,29 +491,3 @@ export function createFormulaPreview(
         return formatSmall(formula.evaluate());
     });
 }
-
-/**
- * Utility for converting a modifier into a formula. Takes the input for this formula as the base parameter.
- * @param modifier The modifier to convert to the formula
- * @param base An existing formula or processed DecimalSource that will be the input to the formula
- */
-export function modifierToFormula<T extends GenericFormula>(
-    modifier: WithRequired<Modifier, "revert">,
-    base: T
-): T;
-export function modifierToFormula(modifier: Modifier, base: FormulaSource): GenericFormula;
-export function modifierToFormula(modifier: Modifier, base: FormulaSource) {
-    return new Formula({
-        inputs: [base],
-        evaluate: val => modifier.apply(val),
-        invert:
-            "revert" in modifier && modifier.revert != null
-                ? (val, lhs) => {
-                      if (lhs instanceof Formula && lhs.hasVariable()) {
-                          return lhs.invert(modifier.revert!(val));
-                      }
-                      throw new Error("Could not invert due to no input being a variable");
-                  }
-                : undefined
-    });
-}
diff --git a/src/features/action.tsx b/src/features/action.tsx
index afd8021..46f0e72 100644
--- a/src/features/action.tsx
+++ b/src/features/action.tsx
@@ -36,7 +36,7 @@ import { ClickableOptions } from "./clickables/clickable";
 export const ActionType = Symbol("Action");
 
 /**
- * An object that configures a {@link Action}.
+ * An object that configures an {@link Action}.
  */
 export interface ActionOptions extends Omit<ClickableOptions, "onClick" | "onHold"> {
     /** The cooldown during which the action cannot be performed again, in seconds. */
@@ -71,7 +71,7 @@ export interface BaseAction {
     [GatherProps]: () => Record<string, unknown>;
 }
 
-/** An object that represens a feature that can be clicked upon, and then have a cooldown before they can be clicked again. */
+/** An object that represents a feature that can be clicked upon, and then has a cooldown before it can be clicked again. */
 export type Action<T extends ActionOptions> = Replace<
     T & BaseAction,
     {
diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx
index fd96c77..c17422b 100644
--- a/src/game/modifiers.tsx
+++ b/src/game/modifiers.tsx
@@ -10,6 +10,8 @@ import { convertComputable } from "util/computed";
 import { createLazyProxy } from "util/proxies";
 import { renderJSX } from "util/vue";
 import { computed, unref } from "vue";
+import Formula from "./formulas/formulas";
+import { FormulaSource, GenericFormula } from "./formulas/types";
 
 /**
  * An object that can be used to apply or unapply some modification to a number.
@@ -21,7 +23,9 @@ export interface Modifier {
     /** Applies some operation on the input and returns the result. */
     apply: (gain: DecimalSource) => DecimalSource;
     /** Reverses the operation applied by the apply property. Required by some features. */
-    revert?: (gain: DecimalSource) => DecimalSource;
+    invert?: (gain: DecimalSource) => DecimalSource;
+    /** Get a formula for this modifier. Required by some features. */
+    getFormula?: (gain: FormulaSource) => GenericFormula;
     /**
      * Whether or not this modifier should be considered enabled.
      * Typically for use with modifiers passed into {@link createSequentialModifier}.
@@ -39,11 +43,11 @@ export interface Modifier {
  */
 export type ModifierFromOptionalParams<T, S> = T extends undefined
     ? S extends undefined
-        ? Omit<WithRequired<Modifier, "revert">, "description" | "enabled">
-        : Omit<WithRequired<Modifier, "revert" | "enabled">, "description">
+        ? Omit<WithRequired<Modifier, "invert">, "description" | "enabled">
+        : Omit<WithRequired<Modifier, "invert" | "enabled">, "description">
     : S extends undefined
-    ? Omit<WithRequired<Modifier, "revert" | "description">, "enabled">
-    : WithRequired<Modifier, "revert" | "enabled" | "description">;
+    ? Omit<WithRequired<Modifier, "invert" | "description">, "enabled">
+    : WithRequired<Modifier, "invert" | "enabled" | "description">;
 
 /** An object that configures an additive modifier via {@link createAdditiveModifier}. */
 export interface AdditiveModifierOptions {
@@ -72,7 +76,8 @@ export function createAdditiveModifier<T extends AdditiveModifierOptions>(
         const processedEnabled = enabled == null ? undefined : convertComputable(enabled);
         return {
             apply: (gain: DecimalSource) => Decimal.add(gain, unref(processedAddend)),
-            revert: (gain: DecimalSource) => Decimal.sub(gain, unref(processedAddend)),
+            invert: (gain: DecimalSource) => Decimal.sub(gain, unref(processedAddend)),
+            getFormula: (gain: FormulaSource) => Formula.add(gain, processedAddend),
             enabled: processedEnabled,
             description:
                 description == null
@@ -133,7 +138,8 @@ export function createMultiplicativeModifier<T extends MultiplicativeModifierOpt
         const processedEnabled = enabled == null ? undefined : convertComputable(enabled);
         return {
             apply: (gain: DecimalSource) => Decimal.times(gain, unref(processedMultiplier)),
-            revert: (gain: DecimalSource) => Decimal.div(gain, unref(processedMultiplier)),
+            invert: (gain: DecimalSource) => Decimal.div(gain, unref(processedMultiplier)),
+            getFormula: (gain: FormulaSource) => Formula.times(gain, processedMultiplier),
             enabled: processedEnabled,
             description:
                 description == null
@@ -206,7 +212,7 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>(
                 }
                 return result;
             },
-            revert: (gain: DecimalSource) => {
+            invert: (gain: DecimalSource) => {
                 let result = gain;
                 if (supportLowNumbers) {
                     result = Decimal.add(result, 1);
@@ -217,6 +223,10 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>(
                 }
                 return result;
             },
+            getFormula: (gain: FormulaSource) =>
+                supportLowNumbers
+                    ? Formula.add(gain, 1).pow(processedExponent).sub(1)
+                    : Formula.pow(gain, processedExponent),
             enabled: processedEnabled,
             description:
                 description == null
@@ -259,9 +269,9 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>(
  */
 export function createSequentialModifier<
     T extends Modifier[],
-    S = T extends WithRequired<Modifier, "revert">[]
-        ? WithRequired<Modifier, "description" | "revert">
-        : Omit<WithRequired<Modifier, "description">, "revert">
+    S = T extends WithRequired<Modifier, "invert">[]
+        ? WithRequired<Modifier, "description" | "invert">
+        : Omit<WithRequired<Modifier, "description">, "invert">
 >(modifiersFunc: () => T): S {
     return createLazyProxy(() => {
         const modifiers = modifiersFunc();
@@ -271,12 +281,19 @@ export function createSequentialModifier<
                 modifiers
                     .filter(m => unref(m.enabled) !== false)
                     .reduce((gain, modifier) => modifier.apply(gain), gain),
-            revert: modifiers.every(m => m.revert != null)
+            invert: modifiers.every(m => m.invert != null)
                 ? (gain: DecimalSource) =>
                       modifiers
                           .filter(m => unref(m.enabled) !== false)
                           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                          .reduceRight((gain, modifier) => modifier.revert!(gain), gain)
+                          .reduceRight((gain, modifier) => modifier.invert!(gain), gain)
+                : undefined,
+            getFormula: modifiers.every(m => m.getFormula != null)
+                ? (gain: FormulaSource) =>
+                      modifiers
+                          .filter(m => unref(m.enabled) !== false)
+                          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+                          .reduce((acc, curr) => curr.getFormula!(acc), gain)
                 : undefined,
             enabled: computed(() => modifiers.filter(m => unref(m.enabled) !== false).length > 0),
             description: jsx(() => (