diff --git a/fabric-tool-attribute-api-v1/build.gradle b/fabric-tool-attribute-api-v1/build.gradle
index 9240a3e8d..b54a3c09f 100644
--- a/fabric-tool-attribute-api-v1/build.gradle
+++ b/fabric-tool-attribute-api-v1/build.gradle
@@ -1,5 +1,5 @@
 archivesBaseName = "fabric-tool-attribute-api-v1"
-version = getSubprojectVersion(project, "1.1.4")
+version = getSubprojectVersion(project, "1.2.0")
 
 dependencies {
     compile project(path: ':fabric-api-base', configuration: 'dev')
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/DynamicAttributeTool.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/DynamicAttributeTool.java
index 7592ac206..845251563 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/DynamicAttributeTool.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/DynamicAttributeTool.java
@@ -68,7 +68,7 @@ public interface DynamicAttributeTool {
 	 * @param stack The item stack being used to mine the block
 	 * @param user  The current user of the tool, or null if there isn't any
 	 * @return The mining speed multiplier of the item. 8.0 is equal to a diamond pick.
-	 * @deprecated Use {@link #getMiningLevel(Tag, BlockState, ItemStack, LivingEntity)} to detect tag and block.
+	 * @deprecated Use {@link #getMiningSpeedMultiplier(Tag, BlockState, ItemStack, LivingEntity)} to detect tag and block.
 	 */
 	// nullable on user once we have an official @Nullable annotation in
 	@Deprecated
@@ -91,8 +91,9 @@ public interface DynamicAttributeTool {
 	}
 
 	/**
-	 * Post process the mining speed, can be used to change tool speed regardless if the tool is effective.
-	 * Useful if you want to change the mining speed even if it is not effective.
+	 * Post process the mining speed, this takes place after the mining speed has been calculated.
+	 *
+	 * <p>This allows bypassing the regular computation formula.
 	 *
 	 * @param tag          The tool tag the item stack is handled by
 	 * @param state        The block to mine
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/ToolManager.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/ToolManager.java
index 9d0b03b17..fb968f4dc 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/ToolManager.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/api/tool/attribute/v1/ToolManager.java
@@ -36,7 +36,20 @@ public final class ToolManager {
 	 * @return whether the tool is effective
 	 */
 	public static boolean handleIsEffectiveOn(BlockState state, ItemStack stack, /* @Nullable */ LivingEntity user) {
-		return stack.isEffectiveOn(state) || handleIsEffectiveOnIgnoresVanilla(state, stack, user);
+		return stack.isEffectiveOn(state) || handleIsEffectiveOnIgnoresVanilla(state, stack, user, false);
+	}
+
+	/**
+	 * Handles if the tool is effective on a block, ignores vanilla tools on vanilla blocks.
+	 *
+	 * @param state the block state to break
+	 * @param stack the item stack involved with breaking the block
+	 * @param user  the user involved in breaking the block, null if not applicable.
+	 * @param vanillaResult whether the tool is considered effective by vanilla
+	 * @return whether the tool is effective
+	 */
+	public static boolean handleIsEffectiveOnIgnoresVanilla(BlockState state, ItemStack stack, /* @Nullable */ LivingEntity user, boolean vanillaResult) {
+		return ToolManagerImpl.handleIsEffectiveOnIgnoresVanilla(state, stack, user, vanillaResult);
 	}
 
 	/**
@@ -48,7 +61,7 @@ public final class ToolManager {
 	 * @return whether the tool is effective
 	 */
 	public static boolean handleIsEffectiveOnIgnoresVanilla(BlockState state, ItemStack stack, /* @Nullable */ LivingEntity user) {
-		return ToolManagerImpl.handleIsEffectiveOnIgnoresVanilla(state, stack, user);
+		return ToolManagerImpl.handleIsEffectiveOnIgnoresVanilla(state, stack, user, false);
 	}
 
 	/**
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/ToolManagerImpl.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/ToolManagerImpl.java
index 89bf90a9a..c4b39fb42 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/ToolManagerImpl.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/ToolManagerImpl.java
@@ -168,7 +168,7 @@ public final class ToolManagerImpl {
 	 * Hook for ItemStack.isEffectiveOn and similar methods.
 	 */
 	//TODO: nullable on user once we have an official @Nullable annotation in
-	public static boolean handleIsEffectiveOnIgnoresVanilla(BlockState state, ItemStack stack, LivingEntity user) {
+	public static boolean handleIsEffectiveOnIgnoresVanilla(BlockState state, ItemStack stack, LivingEntity user, boolean vanillaResult) {
 		for (Map.Entry<Tag<Item>, Event<ToolHandler>> eventEntry : HANDLER_MAP.entrySet()) {
 			if (stack.getItem().isIn(eventEntry.getKey())) {
 				ActionResult effective = eventEntry.getValue().invoker().isEffectiveOn(eventEntry.getKey(), state, stack, user);
@@ -180,7 +180,7 @@ public final class ToolManagerImpl {
 
 		EntryImpl entry = (EntryImpl) entryNullable(state.getBlock());
 
-		return entry != null && entry.defaultValue.get();
+		return (entry != null && entry.defaultValue.get()) || (entry == null && vanillaResult);
 	}
 
 	public static float handleBreakingSpeedIgnoresVanilla(BlockState state, ItemStack stack, /* @Nullable */ LivingEntity user) {
@@ -190,33 +190,25 @@ public final class ToolManagerImpl {
 
 		for (Map.Entry<Tag<Item>, Event<ToolHandler>> eventEntry : HANDLER_MAP.entrySet()) {
 			if (stack.getItem().isIn(eventEntry.getKey())) {
-				ActionResult effective = eventEntry.getValue().invoker().isEffectiveOn(eventEntry.getKey(), state, stack, user);
+				TypedActionResult<Float> speedMultiplier = Objects.requireNonNull(eventEntry.getValue().invoker().getMiningSpeedMultiplier(eventEntry.getKey(), state, stack, user));
 
-				if (effective.isAccepted()) {
-					TypedActionResult<Float> speedMultiplier = Objects.requireNonNull(eventEntry.getValue().invoker().getMiningSpeedMultiplier(eventEntry.getKey(), state, stack, user));
+				if (speedMultiplier.getResult().isAccepted()) {
+					handled = true;
 
-					if (speedMultiplier.getResult().isAccepted()) {
-						handled = true;
-
-						if (speedMultiplier.getValue() > breakingSpeed) {
-							breakingSpeed = speedMultiplier.getValue();
-							handledTag = eventEntry.getKey();
-						}
+					if (speedMultiplier.getValue() > breakingSpeed) {
+						breakingSpeed = speedMultiplier.getValue();
+						handledTag = eventEntry.getKey();
 					}
 				}
 
-				effective = general().invoker().isEffectiveOn(eventEntry.getKey(), state, stack, user);
+				speedMultiplier = Objects.requireNonNull(general().invoker().getMiningSpeedMultiplier(eventEntry.getKey(), state, stack, user));
 
-				if (effective.isAccepted()) {
-					TypedActionResult<Float> speedMultiplier = Objects.requireNonNull(general().invoker().getMiningSpeedMultiplier(eventEntry.getKey(), state, stack, user));
+				if (speedMultiplier.getResult().isAccepted()) {
+					handled = true;
 
-					if (speedMultiplier.getResult().isAccepted()) {
-						handled = true;
-
-						if (speedMultiplier.getValue() > breakingSpeed) {
-							breakingSpeed = speedMultiplier.getValue();
-							handledTag = eventEntry.getKey();
-						}
+					if (speedMultiplier.getValue() > breakingSpeed) {
+						breakingSpeed = speedMultiplier.getValue();
+						handledTag = eventEntry.getKey();
 					}
 				}
 			}
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsModdedBlocksToolHandler.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsModdedBlocksToolHandler.java
index 766c9deb7..2df377399 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsModdedBlocksToolHandler.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsModdedBlocksToolHandler.java
@@ -53,8 +53,12 @@ public class ModdedToolsModdedBlocksToolHandler implements ToolManagerImpl.ToolH
 	@Override
 	public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
 		if (stack.getItem() instanceof DynamicAttributeTool) {
-			float multiplier = ((DynamicAttributeTool) stack.getItem()).getMiningSpeedMultiplier(tag, state, stack, user);
-			if (multiplier != 1.0F) return TypedActionResult.success(multiplier);
+			ToolManagerImpl.Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
+
+			if (entry != null && entry.getMiningLevel(tag) > 0) {
+				float multiplier = ((DynamicAttributeTool) stack.getItem()).getMiningSpeedMultiplier(tag, state, stack, user);
+				if (multiplier != 1.0F) return TypedActionResult.success(multiplier);
+			}
 		}
 
 		return TypedActionResult.pass(1.0F);
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsVanillaBlocksToolHandler.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsVanillaBlocksToolHandler.java
index b80cd9d56..c3841a0e0 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsVanillaBlocksToolHandler.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ModdedToolsVanillaBlocksToolHandler.java
@@ -63,8 +63,7 @@ public class ModdedToolsVanillaBlocksToolHandler implements ToolManagerImpl.Tool
 			if (miningLevel < 0) return ActionResult.PASS;
 
 			ToolItem vanillaItem = getVanillaItem(miningLevel);
-			boolean effective = vanillaItem.isEffectiveOn(state) || vanillaItem.getMiningSpeedMultiplier(new ItemStack(vanillaItem), state) != 1.0F;
-			return effective ? ActionResult.SUCCESS : ActionResult.PASS;
+			return vanillaItem.isEffectiveOn(state) ? ActionResult.SUCCESS : ActionResult.PASS;
 		}
 
 		return ActionResult.PASS;
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ShearsVanillaBlocksToolHandler.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ShearsVanillaBlocksToolHandler.java
index 461fd0f65..14c4bb656 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ShearsVanillaBlocksToolHandler.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/ShearsVanillaBlocksToolHandler.java
@@ -50,9 +50,9 @@ public class ShearsVanillaBlocksToolHandler implements ToolManagerImpl.ToolHandl
 
 		if (!(stack.getItem() instanceof DynamicAttributeTool)) {
 			if (!(stack.getItem() instanceof ShearsItem)) {
-				return vanillaItem.isEffectiveOn(state) || vanillaItem.getMiningSpeedMultiplier(new ItemStack(vanillaItem), state) != 1.0F ? ActionResult.SUCCESS : ActionResult.PASS;
+				return vanillaItem.isEffectiveOn(state) ? ActionResult.SUCCESS : ActionResult.PASS;
 			} else {
-				return stack.getItem().isEffectiveOn(state) || stack.getItem().getMiningSpeedMultiplier(stack, state) != 1.0F ? ActionResult.SUCCESS : ActionResult.PASS;
+				return stack.getItem().isEffectiveOn(state) ? ActionResult.SUCCESS : ActionResult.PASS;
 			}
 		}
 
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/VanillaToolsModdedBlocksToolHandler.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/VanillaToolsModdedBlocksToolHandler.java
index b47cb151a..7efc70a3c 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/VanillaToolsModdedBlocksToolHandler.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/impl/tool/attribute/handlers/VanillaToolsModdedBlocksToolHandler.java
@@ -54,8 +54,12 @@ public class VanillaToolsModdedBlocksToolHandler implements ToolManagerImpl.Tool
 	@Override
 	public TypedActionResult<Float> getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
 		if (!(stack.getItem() instanceof DynamicAttributeTool)) {
-			float multiplier = stack.getItem() instanceof ToolItem ? ((ToolItem) stack.getItem()).getMaterial().getMiningSpeedMultiplier() : stack.getItem().getMiningSpeedMultiplier(stack, state);
-			if (multiplier != 1.0F) return TypedActionResult.success(multiplier);
+			ToolManagerImpl.Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
+
+			if (entry != null && entry.getMiningLevel(tag) >= 0 && tag.contains(stack.getItem())) {
+				float multiplier = stack.getItem() instanceof ToolItem ? ((ToolItem) stack.getItem()).getMaterial().getMiningSpeedMultiplier() : stack.getItem().getMiningSpeedMultiplier(stack, state);
+				if (multiplier != 1.0F) return TypedActionResult.success(multiplier);
+			}
 		}
 
 		return TypedActionResult.pass(1.0F);
diff --git a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/mixin/tool/attribute/MixinItemStack.java b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/mixin/tool/attribute/MixinItemStack.java
index ba93e3c1c..084ed6451 100644
--- a/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/mixin/tool/attribute/MixinItemStack.java
+++ b/fabric-tool-attribute-api-v1/src/main/java/net/fabricmc/fabric/mixin/tool/attribute/MixinItemStack.java
@@ -42,9 +42,7 @@ public abstract class MixinItemStack {
 
 	@Inject(at = @At("RETURN"), method = "isEffectiveOn", cancellable = true)
 	public void isEffectiveOn(BlockState state, CallbackInfoReturnable<Boolean> info) {
-		if (!info.getReturnValueZ()) {
-			info.setReturnValue(ToolManager.handleIsEffectiveOnIgnoresVanilla(state, (ItemStack) (Object) this, null));
-		}
+		info.setReturnValue(ToolManager.handleIsEffectiveOnIgnoresVanilla(state, (ItemStack) (Object) this, null, info.getReturnValueZ()));
 	}
 
 	@Inject(at = @At("RETURN"), method = "getMiningSpeedMultiplier", cancellable = true)
diff --git a/fabric-tool-attribute-api-v1/src/testmod/java/net/fabricmc/fabric/test/tool/attribute/ToolAttributeTest.java b/fabric-tool-attribute-api-v1/src/testmod/java/net/fabricmc/fabric/test/tool/attribute/ToolAttributeTest.java
index 68f02a05b..f1866260c 100644
--- a/fabric-tool-attribute-api-v1/src/testmod/java/net/fabricmc/fabric/test/tool/attribute/ToolAttributeTest.java
+++ b/fabric-tool-attribute-api-v1/src/testmod/java/net/fabricmc/fabric/test/tool/attribute/ToolAttributeTest.java
@@ -18,11 +18,15 @@ package net.fabricmc.fabric.test.tool.attribute;
 
 import net.minecraft.block.Block;
 import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.Material;
 import net.minecraft.block.MaterialColor;
 import net.minecraft.entity.LivingEntity;
 import net.minecraft.item.BlockItem;
 import net.minecraft.item.Item;
 import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.item.ToolItem;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.sound.BlockSoundGroup;
 import net.minecraft.tag.Tag;
@@ -30,51 +34,113 @@ import net.minecraft.util.Identifier;
 import net.minecraft.util.registry.Registry;
 
 import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.event.server.ServerTickCallback;
 import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
 import net.fabricmc.fabric.api.object.builder.v1.block.FabricMaterialBuilder;
 import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
 import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
-import net.fabricmc.fabric.api.event.server.ServerTickCallback;
 
 public class ToolAttributeTest implements ModInitializer {
-	private boolean hasValidatedTags = false;
+	private static final float DEFAULT_BREAK_SPEED = 1.0F;
+	private static final float TOOL_BREAK_SPEED = 10.0F;
+
+	private boolean hasValidated = false;
+
+	Block gravelBlock;
+	Block stoneBlock;
+	Item testShovel;
+	Item testPickaxe;
 
 	@Override
 	public void onInitialize() {
 		// Register a custom shovel that has a mining level of 2 (iron) dynamically.
-		Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_shovel"), new TestShovel(new Item.Settings()));
+		testShovel = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_shovel"), new TestTool(new Item.Settings(), FabricToolTags.SHOVELS));
+		//Register a custom pickaxe that has a mining level of 2 (iron) dynamically.
+		testPickaxe = Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "test_pickaxe"), new TestTool(new Item.Settings(), FabricToolTags.PICKAXES));
 		// Register a block that requires a shovel that is as strong or stronger than an iron one.
-		Block block = Registry.register(Registry.BLOCK, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_block"),
+		gravelBlock = Registry.register(Registry.BLOCK, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_gravel_block"),
 				new Block(FabricBlockSettings.of(new FabricMaterialBuilder(MaterialColor.SAND).build(), MaterialColor.STONE)
 						.breakByTool(FabricToolTags.SHOVELS, 2)
 						.requiresTool()
 						.strength(0.6F)
 						.sounds(BlockSoundGroup.GRAVEL)));
-		Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_block"), new BlockItem(block, new Item.Settings()));
+		Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_gravel_block"), new BlockItem(gravelBlock, new Item.Settings()));
+		// Register a block that requires a pickaxe that is as strong or stronger than an iron one.
+		stoneBlock = Registry.register(Registry.BLOCK, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_stone_block"),
+				new Block(FabricBlockSettings.of(Material.STONE, MaterialColor.STONE)
+						.breakByTool(FabricToolTags.PICKAXES, 2)
+						.requiresTool()
+						.strength(0.6F)
+						.sounds(BlockSoundGroup.STONE)));
+		Registry.register(Registry.ITEM, new Identifier("fabric-tool-attribute-api-v1-testmod", "hardened_stone_block"), new BlockItem(stoneBlock, new Item.Settings()));
 
-		ServerTickCallback.EVENT.register(this::validateTags);
+		ServerTickCallback.EVENT.register(this::validate);
 	}
 
-	private void validateTags(MinecraftServer server) {
-		if (hasValidatedTags) {
+	private void validate(MinecraftServer server) {
+		if (hasValidated) {
 			return;
 		}
 
-		hasValidatedTags = true;
+		hasValidated = true;
 
 		if (FabricToolTags.PICKAXES.values().isEmpty()) {
 			throw new AssertionError("Failed to load tool tags");
 		}
+
+		//Test we haven't broken vanilla behavior
+		testToolOnBlock(new ItemStack(Items.STONE_PICKAXE), Blocks.GRAVEL, false, 1.0F);
+		testToolOnBlock(new ItemStack(Items.IRON_PICKAXE), Blocks.STONE, true, ((ToolItem) Items.IRON_PICKAXE).getMaterial().getMiningSpeedMultiplier());
+		testToolOnBlock(new ItemStack(Items.IRON_PICKAXE), Blocks.OBSIDIAN, false, ((ToolItem) Items.IRON_PICKAXE).getMaterial().getMiningSpeedMultiplier());
+		testToolOnBlock(new ItemStack(Items.STONE_SHOVEL), Blocks.STONE, false, 1.0F);
+		testToolOnBlock(new ItemStack(Items.STONE_SHOVEL), Blocks.GRAVEL, false, ((ToolItem) Items.STONE_SHOVEL).getMaterial().getMiningSpeedMultiplier());
+
+		//Test vanilla tools don't bypass fabric mining levels
+		testToolOnBlock(new ItemStack(Items.STONE_PICKAXE), stoneBlock, false, ((ToolItem) Items.STONE_PICKAXE).getMaterial().getMiningSpeedMultiplier());
+		testToolOnBlock(new ItemStack(Items.IRON_PICKAXE), stoneBlock, true, ((ToolItem) Items.IRON_PICKAXE).getMaterial().getMiningSpeedMultiplier());
+		testToolOnBlock(new ItemStack(Items.STONE_SHOVEL), gravelBlock, false, ((ToolItem) Items.STONE_SHOVEL).getMaterial().getMiningSpeedMultiplier());
+		testToolOnBlock(new ItemStack(Items.IRON_SHOVEL), gravelBlock, true, ((ToolItem) Items.IRON_SHOVEL).getMaterial().getMiningSpeedMultiplier());
+
+		//Test vanilla tools respect fabric mining tags
+		testToolOnBlock(new ItemStack(Items.IRON_PICKAXE), gravelBlock, false, DEFAULT_BREAK_SPEED);
+		testToolOnBlock(new ItemStack(Items.IRON_SHOVEL), stoneBlock, false, DEFAULT_BREAK_SPEED);
+
+		//Test dynamic tools don't bypass mining level
+		testToolOnBlock(new ItemStack(testPickaxe), Blocks.OBSIDIAN, false, TOOL_BREAK_SPEED);
+
+		//Test dynamic tools respect fabric mining tags
+		testToolOnBlock(new ItemStack(testPickaxe), gravelBlock, false, DEFAULT_BREAK_SPEED);
+		testToolOnBlock(new ItemStack(testShovel), stoneBlock, false, DEFAULT_BREAK_SPEED);
+
+		//Test dynamic tools on vanilla blocks
+		testToolOnBlock(new ItemStack(testShovel), Blocks.STONE, false, DEFAULT_BREAK_SPEED);
+		testToolOnBlock(new ItemStack(testShovel), Blocks.GRAVEL, false, TOOL_BREAK_SPEED);
+		testToolOnBlock(new ItemStack(testPickaxe), Blocks.GRAVEL, false, DEFAULT_BREAK_SPEED);
+		testToolOnBlock(new ItemStack(testPickaxe), Blocks.STONE, true, TOOL_BREAK_SPEED);
 	}
 
-	private static class TestShovel extends Item implements DynamicAttributeTool {
-		private TestShovel(Settings settings) {
+	private void testToolOnBlock(ItemStack item, Block block, boolean inEffective, float inSpeed) {
+		boolean effective = item.isEffectiveOn(block.getDefaultState());
+		float speed = item.getMiningSpeedMultiplier(block.getDefaultState());
+
+		if (inEffective != effective) {
+			throw new AssertionError("Effective check incorrect for " + Registry.ITEM.getId(item.getItem()) + " breaking " + Registry.BLOCK.getId(block) + " got " + effective);
+		} else if (inSpeed != speed) {
+			throw new AssertionError("Speed check incorrect for " + Registry.ITEM.getId(item.getItem()) + " breaking " + Registry.BLOCK.getId(block) + " got " + speed);
+		}
+	}
+
+	private static class TestTool extends Item implements DynamicAttributeTool {
+		final Tag<Item> toolType;
+
+		private TestTool(Settings settings, Tag<Item> toolType) {
 			super(settings);
+			this.toolType = toolType;
 		}
 
 		@Override
 		public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
-			if (tag.equals(FabricToolTags.SHOVELS)) {
+			if (tag.equals(toolType)) {
 				return 2;
 			}
 
@@ -83,11 +149,11 @@ public class ToolAttributeTest implements ModInitializer {
 
 		@Override
 		public float getMiningSpeedMultiplier(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
-			if (tag.equals(FabricToolTags.SHOVELS)) {
-				return 10.0F;
+			if (tag.equals(toolType)) {
+				return TOOL_BREAK_SPEED;
 			}
 
-			return 1.0F;
+			return DEFAULT_BREAK_SPEED;
 		}
 	}
 }
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_gravel_block.json
similarity index 100%
rename from fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_block.json
rename to fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_gravel_block.json
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_stone_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_stone_block.json
new file mode 100644
index 000000000..a99df56e8
--- /dev/null
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/blockstates/hardened_stone_block.json
@@ -0,0 +1,5 @@
+{
+  "variants": {
+    "": { "model": "block/stone" }
+  }
+}
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_gravel_block.json
similarity index 100%
rename from fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_block.json
rename to fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_gravel_block.json
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_stone_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_stone_block.json
new file mode 100644
index 000000000..e664fbe59
--- /dev/null
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/hardened_stone_block.json
@@ -0,0 +1,3 @@
+{
+  "parent": "block/stone"
+}
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/test_pickaxe.json b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/test_pickaxe.json
new file mode 100644
index 000000000..f0f76884b
--- /dev/null
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/assets/fabric-tool-attribute-api-v1-testmod/models/item/test_pickaxe.json
@@ -0,0 +1,6 @@
+{
+  "parent": "item/generated",
+  "textures": {
+    "layer0": "item/apple"
+  }
+}
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_gravel_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_gravel_block.json
new file mode 100644
index 000000000..acbbe77fe
--- /dev/null
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_gravel_block.json
@@ -0,0 +1,19 @@
+{
+  "type": "minecraft:block",
+  "pools": [
+    {
+      "rolls": 1,
+      "entries": [
+        {
+          "type": "minecraft:item",
+          "name": "fabric-tool-attribute-api-v1-testmod:hardened_gravel_block"
+        }
+      ],
+      "conditions": [
+        {
+          "condition": "minecraft:survives_explosion"
+        }
+      ]
+    }
+  ]
+}
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_block.json b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_stone_block.json
similarity index 95%
rename from fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_block.json
rename to fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_stone_block.json
index 44936390f..e7c9a5689 100644
--- a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_block.json
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric-tool-attribute-api-v1-testmod/loot_tables/blocks/hardened_stone_block.json
@@ -6,7 +6,7 @@
       "entries": [
         {
           "type": "minecraft:item",
-          "name": "fabric-tool-attribute-api-v1-testmod:hardened_block"
+          "name": "fabric-tool-attribute-api-v1-testmod:hardened_stone_block"
         }
       ],
       "conditions": [
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/pickaxes.json b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/pickaxes.json
new file mode 100644
index 000000000..8c6564e28
--- /dev/null
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/pickaxes.json
@@ -0,0 +1,6 @@
+{
+  "replace": false,
+  "values": [
+    "fabric-tool-attribute-api-v1-testmod:test_pickaxe"
+  ]
+}
\ No newline at end of file
diff --git a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/shovels.json b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/shovels.json
index e58d9239c..cbc529463 100644
--- a/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/shovels.json
+++ b/fabric-tool-attribute-api-v1/src/testmod/resources/data/fabric/tags/items/shovels.json
@@ -3,4 +3,4 @@
   "values": [
     "fabric-tool-attribute-api-v1-testmod:test_shovel"
   ]
-}
+}
\ No newline at end of file