diff --git a/substrate/environmental/src/lib.rs b/substrate/environmental/src/lib.rs
index b7fc47ea5067d672dd70900df1cc695c2ba9391c..cd278f812335c2ac965e79dd50b3387258fb3502 100644
--- a/substrate/environmental/src/lib.rs
+++ b/substrate/environmental/src/lib.rs
@@ -22,9 +22,21 @@ pub fn using_environment<'a, T: 'a, R, S, F: FnOnce() -> R>(
 	protected: &'a mut T,
 	f: F
 ) -> R {
-	global.with(|r| *r.borrow_mut() = protected as *mut T as *mut S);
+	// store the `protected` reference as a pointer so we can provide it to logic running within
+	// `f`.
+	// while re record this pointer (while it's non-zero) we guarantee:
+	// - it will only be used once at any time (no reentrancy);
+	// - that no other thread will use it; and
+	// - that we do not use the original mutating reference while the pointer.
+	// exists.
+	let original = global.with(|r| {
+		let mut b = r.borrow_mut();
+		let o = *b;
+		*b = protected as *mut T as *mut S;
+		o
+	});
 	let r = f();
-	global.with(|r| *r.borrow_mut() = 0 as *mut S);
+	global.with(|r| *r.borrow_mut() = original);
 	r
 }
 
@@ -35,8 +47,8 @@ pub fn with_environment<'r, R, S, T: 'r, F: FnOnce(&'r mut T) -> R>(
 	global.with(|r| {
 		let br = r.borrow_mut();
 		if *br != 0 as *mut S {
-			// safe because it's only non-zero when it in with_environment, which
-			// is holding on to the underlying reference safely
+			// safe because it's only non-zero when it's being called from using_environment, which
+			// is holding on to the underlying reference (and not using it itself) safely.
 			unsafe {
 				Some(mutator(&mut *(*br as *mut S as *mut T)))
 			}