Interrupts and button pushes don't mix AT ALL. Buttons have a phenomenon knows a bounce. Just before the contacts close they "bounce" making and breaking contact. If for example using a pin change interrupt with a button you may enter and exit sleep mode a bunch of times before the button stabilizes. Buttons need debounced, a technique that makes sure that the button state is stable before reading that button.
The best way to debounce a button is to read the state of the button in regular intervals, 1ms for example. If the state of the button stays constant for at least 50ms the button can be considered stable.
The way i normally write such a routine is check the button every 1ms. If a debounce event is not in progress and the current button state does not match the past button state, start a debounce event. Continue checking the button every 1ms but increment a counter every time a button read occurs. Normally i'll start at 50. If the button is lows i'll decrement and if the button is high i'll increment. If you get to 100 then the button is high and if you get to 0 the button is low. Reset the start variable back to 50 and set debounce event to false.
In your case i would use the pin change interrupt to wake the micro but then impose a mandatory debounce. If the debounce passes then stay awake. If the debouce fails, meaning that a button was not pushed, then fall back to sleep.
volatile
(so the compiler knows it can change in the ISR and doesn't optimise it away). For example:volatile boolean flag;
\$\endgroup\$